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