1 /* 2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package javafx.scene.control.test.treeview; 26 27 import java.util.ArrayList; 28 import static javafx.commons.Consts.BTN_SET_ON_EDIT_EVENT_HANDLERS; 29 import javafx.event.ActionEvent; 30 import javafx.event.Event; 31 import javafx.event.EventHandler; 32 import javafx.geometry.Orientation; 33 import javafx.scene.Scene; 34 import javafx.scene.control.*; 35 import javafx.scene.control.test.treetable.ResetButtonNames; 36 import static javafx.scene.control.test.treeview.TreeViewConstants.ROOT_NAME; 37 import javafx.scene.control.test.utils.CommonPropertiesScene; 38 import javafx.scene.control.test.utils.ptables.NodeControllerFactory; 39 import javafx.scene.control.test.utils.ptables.NodeControllerFactory.NodesStorage; 40 import javafx.scene.control.test.utils.ptables.PropertiesTable; 41 import javafx.scene.control.test.utils.ptables.PropertyTablesFactory; 42 import javafx.scene.control.test.utils.ptables.SpecialTablePropertiesProvider; 43 import javafx.scene.control.test.utils.ptables.TabPaneWithControl; 44 import javafx.scene.input.KeyCode; 45 import javafx.scene.input.KeyEvent; 46 import javafx.scene.layout.HBox; 47 import javafx.scene.layout.VBox; 48 import javafx.util.Callback; 49 import test.javaclient.shared.InteroperabilityApp; 50 import test.javaclient.shared.Utils; 51 52 /** 53 * @author Alexander Kirov 54 */ 55 public class TreeViewNewApp extends InteroperabilityApp implements TreeViewConstants, ResetButtonNames { 56 57 public final static String TESTED_TREEVIEW_ID = "TESTED_TREEVIEW_ID"; 58 public final static String POPULATE_TREE = "POPULATE_TREE"; 59 public final static String TREE_VIEW_TAB_NAME = "TreeView"; 60 61 public static void main(String[] args) { 62 Utils.launch(TreeViewNewApp.class, args); 63 } 64 65 @Override 66 protected Scene getScene() { 67 Scene scene = new TreeViewScene(); 68 Utils.addBrowser(scene); 69 Utils.setTitleToStage(stage, "TreeViewTestApp"); 70 return scene; 71 } 72 73 public static TreeItem searchTreeItem(TreeView treeView, String content) { 74 if (treeView.getRoot() != null) { 75 return recursiveSearch(content, treeView.getRoot()); 76 } 77 return null; 78 } 79 80 protected static TreeItem recursiveSearch(String content, TreeItem<? extends Object> itemToStart) { 81 if (content.equals(itemToStart.getValue())) { 82 return itemToStart; 83 } else { 84 for (TreeItem child : itemToStart.getChildren()) { 85 TreeItem recResult = recursiveSearch(content, child); 86 if (recResult != null) { 87 return recResult; 88 } 89 } 90 return null; 91 } 92 } 93 94 protected class TreeViewScene extends CommonPropertiesScene { 95 96 TreeView testedControl; 97 //TabPane with PropertiesTable. 98 TabPaneWithControl tabPane; 99 PropertiesTable tb; 100 //This list contains all properties tables, which were created during testing. 101 ArrayList<PropertiesTable> allPropertiesTables; 102 103 public TreeViewScene() { 104 super("TreeView", 800, 600); 105 prepareScene(); 106 } 107 108 protected TreeView getNewTestedControl() { 109 TreeView tv = new TreeView(new TreeItem(ROOT_NAME)); 110 tv.setId(TESTED_TREEVIEW_ID); 111 return tv; 112 } 113 114 @Override 115 final protected void prepareScene() { 116 testedControl = getNewTestedControl(); 117 tb = new PropertiesTable(testedControl); 118 119 allPropertiesTables = new ArrayList<PropertiesTable>(); 120 allPropertiesTables.add(tb); 121 122 PropertyTablesFactory.explorePropertiesList(testedControl, tb); 123 PropertyTablesFactory.explorePropertiesList(testedControl.getSelectionModel(), tb); 124 PropertyTablesFactory.explorePropertiesList(testedControl.getFocusModel(), tb); 125 SpecialTablePropertiesProvider.provideForControl(testedControl, tb); 126 127 tb.addCounter(EDIT_START_COUNTER); 128 tb.addCounter(EDIT_COMMIT_COUNTER); 129 tb.addCounter(EDIT_CANCEL_COUNTER); 130 131 tabPane = new TabPaneWithControl("TreeView", tb); 132 getControlOverItem(ROOT_NAME); 133 134 Button hardResetButton = ButtonBuilder.create().id(HARD_RESET_BUTTON_ID).text("Hard reset").build(); 135 hardResetButton.setOnAction(new EventHandler<ActionEvent>() { 136 public void handle(ActionEvent t) { 137 HBox hb = (HBox) getRoot(); 138 hb.getChildren().clear(); 139 prepareMainSceneStructure(); 140 prepareScene(); 141 } 142 }); 143 144 Button softResetButton = ButtonBuilder.create().id(SOFT_RESET_BUTTON_ID).text("Soft reset").build(); 145 softResetButton.setOnAction(new EventHandler<ActionEvent>() { 146 public void handle(ActionEvent t) { 147 refreshProcedure(2); 148 testedControl.getRoot().setValue(ROOT_NAME); 149 TreeItem someNewOneTreeItem = new TreeItem(); 150 testedControl.getRoot().setExpanded(someNewOneTreeItem.isExpanded()); 151 testedControl.getRoot().setGraphic(someNewOneTreeItem.getGraphic()); 152 153 TreeView someNewOneTreeView = new TreeView(); 154 testedControl.setDisable(someNewOneTreeView.isDisabled()); 155 testedControl.setEditable(someNewOneTreeView.isEditable()); 156 testedControl.setShowRoot(someNewOneTreeView.isShowRoot()); 157 testedControl.getSelectionModel().setSelectionMode(someNewOneTreeView.getSelectionModel().getSelectionMode()); 158 testedControl.setMinHeight(someNewOneTreeView.getMinHeight()); 159 testedControl.setMinWidth(someNewOneTreeView.getMinWidth()); 160 testedControl.setPrefHeight(someNewOneTreeView.getPrefHeight()); 161 testedControl.setPrefWidth(someNewOneTreeView.getPrefWidth()); 162 } 163 }); 164 165 Button populate = new Button("Populate"); 166 populate.setId(POPULATE_TREE); 167 populate.setOnAction(new EventHandler<ActionEvent>() { 168 169 public void handle(ActionEvent t) { 170 TreeItem root = new TreeItem("ROOT"); 171 root.setExpanded(true); 172 for (int i = 0; i < 4; i++) { 173 TreeItem parent = new TreeItem("item-" + String.valueOf(i)); 174 parent.setExpanded(true); 175 root.getChildren().add(parent); 176 for (int j = 0; j < 4; j++) { 177 TreeItem child = new TreeItem("item-" + String.valueOf(i) + "-" + String.valueOf(j)); 178 parent.getChildren().add(child); 179 } 180 } 181 testedControl.setRoot(root); 182 } 183 }); 184 185 HBox hboxWithResetButtons = new HBox(); 186 hboxWithResetButtons.getChildren().addAll(hardResetButton, softResetButton, populate); 187 188 Button autosize = new Button("Autosize"); 189 autosize.setId(AUTOSIZE_BUTTON_ID); 190 autosize.setOnAction(new EventHandler<ActionEvent>() { 191 public void handle(ActionEvent t) { 192 testedControl.autosize(); 193 } 194 }); 195 196 VBox vb = new VBox(); 197 vb.setSpacing(5); 198 //Different action makers. 199 vb.getChildren().addAll(hboxWithResetButtons, autosize, new Separator(Orientation.HORIZONTAL), 200 getTreeViewAddItemController(), new Separator(Orientation.HORIZONTAL), 201 getTreeViewRemoveItemController(), new Separator(Orientation.HORIZONTAL), 202 getTabOverItemThroughGetItemMethodController(), new Separator(Orientation.HORIZONTAL), 203 getTabOverItemController(), new Separator(Orientation.HORIZONTAL), 204 getObjectTitleThroughGetItemMethodController(), new Separator(Orientation.HORIZONTAL), 205 getLineOfItemController(), new Separator(Orientation.HORIZONTAL), 206 getScrollToHBox(), new Separator(Orientation.HORIZONTAL), 207 getEditHBox(), new Separator(Orientation.HORIZONTAL), 208 setEventHandlersHBox()); 209 210 setTestedControl(testedControl); 211 setPropertiesContent(tabPane); 212 setControllersContent(vb); 213 } 214 215 /* 216 * In this function TabPane with control will be refreshed, and all 217 * properties table will be refreshed and cleared. 218 */ 219 private void refreshProcedure(int exceptFirstPropertiesTable) { 220 for (int i = allPropertiesTables.size() - 1; i >= 0; i--) { 221 allPropertiesTables.get(i).refresh(); 222 if (i >= exceptFirstPropertiesTable) { 223 allPropertiesTables.remove(i); 224 } 225 } 226 227 tabPane.removePropertiesTablesExceptFirstOnes(exceptFirstPropertiesTable); 228 229 testedControl.getRoot().getChildren().clear(); 230 } 231 232 protected void getControlOverItem(String name) { 233 TreeItem treeItem = searchTreeItem(name); 234 NodesStorage node = NodeControllerFactory.createFullController(treeItem, tabPane); 235 allPropertiesTables.add(node.pt); 236 tabPane.addPropertiesTable(name, node); 237 } 238 239 protected VBox getTreeViewAddItemController() { 240 VBox vb = new VBox(3); 241 242 final TextField tfParentName = new TextField(); 243 tfParentName.setId(ADD_ITEM_PARENT_TEXT_FIELD_ID); 244 tfParentName.setPromptText("parent name"); 245 246 final TextField tfName = new TextField(); 247 tfName.setId(ADD_ITEM_TEXT_FIELD_ID); 248 tfName.setPromptText("new item name"); 249 250 final TextField tfPosition = new TextField(); 251 tfPosition.setId(ADD_ITEM_POSITION_TEXT_FIELD_ID);; 252 tfPosition.setPromptText("position"); 253 tfPosition.setPrefWidth(50); 254 255 Button button = new Button("add to pos"); 256 button.setId(ADD_ITEM_BUTTON_ID); 257 button.setOnAction(new EventHandler<ActionEvent>() { 258 public void handle(ActionEvent t) { 259 TreeItem treeItem = searchTreeItem(tfParentName.getText()); 260 treeItem.getChildren().add(Integer.parseInt(tfPosition.getText()), new TreeItem(tfName.getText())); 261 } 262 }); 263 264 HBox hb1 = new HBox(3); 265 hb1.getChildren().addAll(new Label("Add child to "), tfParentName); 266 267 HBox hb2 = new HBox(3); 268 hb2.getChildren().addAll(new Label(" named "), tfName); 269 270 HBox hb3 = new HBox(3); 271 hb3.getChildren().addAll(tfPosition, button); 272 273 vb.getChildren().addAll(hb1, hb2, hb3); 274 275 return vb; 276 } 277 278 protected VBox getTreeViewRemoveItemController() { 279 VBox vb = new VBox(3); 280 281 final TextField tfName = new TextField(); 282 tfName.setId(REMOVE_ITEM_TEXT_FIELD_ID); 283 tfName.setPromptText("new item name"); 284 285 Button button = new Button("remove!"); 286 button.setId(REMOVE_ITEM_BUTTON_ID); 287 button.setOnAction(new EventHandler<ActionEvent>() { 288 public void handle(ActionEvent t) { 289 TreeItem treeItem = searchTreeItem(tfName.getText()); 290 treeItem.getParent().getChildren().remove(treeItem); 291 } 292 }); 293 294 HBox hb1 = new HBox(3); 295 hb1.getChildren().addAll(new Label("Named item"), tfName); 296 297 HBox hb2 = new HBox(3); 298 hb2.getChildren().addAll(button); 299 300 vb.getChildren().addAll(hb1, hb2); 301 302 return vb; 303 } 304 305 protected VBox getTabOverItemController() { 306 final TextField tfParentName = new TextField(); 307 tfParentName.setId(GET_CONTROL_OVER_TREEITEM_TEXTFIELD_ID); 308 tfParentName.setPromptText("item name"); 309 310 Button button = new Button("get table over"); 311 button.setId(GET_CONTROL_OVER_TREEITEM_BUTTON_ID); 312 button.setOnAction(new EventHandler<ActionEvent>() { 313 public void handle(ActionEvent t) { 314 getControlOverItem(tfParentName.getText()); 315 } 316 }); 317 318 HBox hb1 = new HBox(3); 319 hb1.getChildren().addAll(tfParentName, button); 320 321 VBox vb = new VBox(); 322 vb.getChildren().addAll(hb1); 323 return vb; 324 } 325 326 protected VBox getObjectTitleThroughGetItemMethodController() { 327 final TextField tfParentName = new TextField(); 328 tfParentName.setPromptText("index"); 329 tfParentName.setPrefWidth(50); 330 331 final TextField content = new TextField(); 332 content.setPromptText("content"); 333 334 Button button = new Button("getTreeItem! index:"); 335 button.setOnAction(new EventHandler<ActionEvent>() { 336 public void handle(ActionEvent t) { 337 TreeItem item = testedControl.getTreeItem(Integer.parseInt(tfParentName.getText())); 338 if (item == null) { 339 content.setText("null"); 340 } else { 341 content.setText(item.getValue().toString()); 342 } 343 } 344 }); 345 346 HBox hb1 = new HBox(3); 347 hb1.getChildren().addAll(new Label("Get tree item at"), tfParentName); 348 349 HBox hb2 = new HBox(3); 350 hb2.getChildren().addAll(button, content); 351 352 VBox vb = new VBox(); 353 vb.getChildren().addAll(hb1, hb2); 354 return vb; 355 } 356 357 protected VBox getTabOverItemThroughGetItemMethodController() { 358 final TextField tfParentName = new TextField(); 359 tfParentName.setPromptText("index"); 360 tfParentName.setPrefWidth(50); 361 362 Button button = new Button("get table over"); 363 button.setOnAction(new EventHandler<ActionEvent>() { 364 public void handle(ActionEvent t) { 365 getControlOverItem(testedControl.getTreeItem(Integer.parseInt(tfParentName.getText())).getValue().toString()); 366 } 367 }); 368 369 HBox hb1 = new HBox(3); 370 hb1.getChildren().addAll(tfParentName, button); 371 372 VBox vb = new VBox(); 373 vb.getChildren().addAll(hb1); 374 return vb; 375 } 376 377 protected VBox getLineOfItemController() { 378 final TextField tfParentName = new TextField(); 379 tfParentName.setPromptText("name"); 380 381 final TextField index = new TextField(); 382 index.setPromptText("found index"); 383 index.setPrefWidth(50); 384 385 Button button = new Button("getRow! index :"); 386 button.setOnAction(new EventHandler<ActionEvent>() { 387 public void handle(ActionEvent t) { 388 int found = testedControl.getRow(searchTreeItem(tfParentName.getText())); 389 index.setText(((Integer) found).toString()); 390 } 391 }); 392 393 HBox hb1 = new HBox(3); 394 hb1.getChildren().addAll(new Label("Get index of"), tfParentName); 395 396 HBox hb2 = new HBox(3); 397 hb2.getChildren().addAll(index, button); 398 399 VBox vb = new VBox(); 400 vb.getChildren().addAll(hb1, hb2); 401 return vb; 402 } 403 404 private HBox getScrollToHBox() { 405 HBox hb = new HBox(); 406 Button button = ButtonBuilder.create().text("ScrollTo").id(SCROLL_TO_BUTTON_ID).build(); 407 final TextField tf = TextFieldBuilder.create().text("0").id(SCROLL_TO_TEXT_FIELD_ID).prefWidth(50).build(); 408 409 button.setOnAction(new EventHandler<ActionEvent>() { 410 public void handle(ActionEvent t) { 411 testedControl.scrollTo(Integer.parseInt(tf.getText())); 412 } 413 }); 414 415 hb.getChildren().addAll(tf, button); 416 return hb; 417 } 418 419 private HBox getEditHBox() { 420 HBox hb = new HBox(); 421 Button button = ButtonBuilder.create().text("Edit").id(EDIT_BUTTON_ID).build(); 422 final TextField tf = TextFieldBuilder.create().promptText("name").id(EDIT_TEXT_FIELD_ID).prefWidth(50).build(); 423 424 button.setOnAction(new EventHandler<ActionEvent>() { 425 public void handle(ActionEvent t) { 426 testedControl.edit(searchTreeItem(tf.getText())); 427 } 428 }); 429 430 hb.getChildren().addAll(tf, button); 431 return hb; 432 } 433 434 private VBox setEventHandlersHBox() { 435 VBox vb = new VBox(); 436 437 Button btn = ButtonBuilder.create() 438 .text("Set onEdit event hadlers") 439 .id(BTN_SET_ON_EDIT_EVENT_HANDLERS) 440 .build(); 441 442 btn.setOnAction(new EventHandler<ActionEvent>() { 443 public void handle(ActionEvent t) { 444 testedControl.setOnEditStart(new EventHandler() { 445 public void handle(Event t) { 446 tb.incrementCounter(EDIT_START_COUNTER); 447 } 448 }); 449 450 testedControl.setOnEditCommit(new EventHandler() { 451 public void handle(Event t) { 452 tb.incrementCounter(EDIT_COMMIT_COUNTER); 453 } 454 }); 455 456 testedControl.setOnEditCancel(new EventHandler() { 457 public void handle(Event t) { 458 tb.incrementCounter(EDIT_CANCEL_COUNTER); 459 } 460 }); 461 } 462 }); 463 464 Button btnAddFactory = ButtonBuilder.create() 465 .text("Set cell factory for editing") 466 .id(SET_CELL_FACTORY_FOR_EDITING) 467 .build(); 468 469 btnAddFactory.setOnAction(new EventHandler<ActionEvent>() { 470 public void handle(ActionEvent t) { 471 testedControl.setCellFactory(new Callback<TreeView<String>, TreeCell<String>>() { 472 @Override 473 public TreeCell<String> call(TreeView<String> p) { 474 return new TextFieldTreeCellImpl(); 475 } 476 }); 477 } 478 }); 479 480 vb.getChildren().addAll(btn, btnAddFactory); 481 return vb; 482 } 483 484 private TreeItem searchTreeItem(String content) { 485 return TreeViewNewApp.searchTreeItem(testedControl, content); 486 } 487 488 private final class TextFieldTreeCellImpl extends TreeCell<String> { 489 490 private TextField textField; 491 492 public TextFieldTreeCellImpl() { 493 } 494 495 @Override 496 public void startEdit() { 497 super.startEdit(); 498 499 if (textField == null) { 500 createTextField(); 501 } 502 setText(null); 503 setGraphic(textField); 504 textField.setText(getString()); 505 textField.requestFocus(); 506 } 507 508 @Override 509 public void cancelEdit() { 510 super.cancelEdit(); 511 setText((String) getItem()); 512 setGraphic(getTreeItem().getGraphic()); 513 } 514 515 @Override 516 public void updateItem(String item, boolean empty) { 517 super.updateItem(item, empty); 518 519 if (empty) { 520 setText(null); 521 setGraphic(null); 522 } else { 523 if (isEditing()) { 524 if (textField != null) { 525 textField.setText(getString()); 526 } 527 setText(null); 528 setGraphic(textField); 529 } else { 530 setText(getString()); 531 setGraphic(getTreeItem().getGraphic()); 532 } 533 } 534 } 535 536 private void createTextField() { 537 textField = new TextField(getString()); 538 textField.setOnKeyReleased(new EventHandler<KeyEvent>() { 539 @Override 540 public void handle(KeyEvent t) { 541 if (t.getCode() == KeyCode.ENTER) { 542 commitEdit(textField.getText()); 543 } else if (t.getCode() == KeyCode.ESCAPE) { 544 cancelEdit(); 545 } 546 } 547 }); 548 } 549 550 private String getString() { 551 return getItem() == null ? "" : getItem().toString(); 552 } 553 } 554 } 555 }