1 /* 2 * Copyright (c) 2018, 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 26 package test.javafx.robot.scene.treetableview; 27 28 import com.sun.glass.ui.Robot; 29 import javafx.application.Application; 30 import javafx.application.Platform; 31 import javafx.scene.control.cell.TreeItemPropertyValueFactory; 32 import javafx.scene.control.TreeItem; 33 import javafx.scene.control.TreeTableColumn; 34 import javafx.scene.control.TreeTableView; 35 import javafx.scene.Scene; 36 import javafx.stage.Stage; 37 import javafx.stage.StageStyle; 38 import javafx.stage.WindowEvent; 39 40 import java.util.concurrent.CountDownLatch; 41 import java.util.concurrent.TimeUnit; 42 43 import org.junit.AfterClass; 44 import org.junit.Assert; 45 import org.junit.BeforeClass; 46 import org.junit.Test; 47 import static org.junit.Assert.fail; 48 49 /* 50 * Test to verify treeTableView resizeColumnToFitContent with 51 * column resize policy set to CONSTRAINED_RESIZE_POLICY. 52 */ 53 public class TreeTableViewResizeColumnToFitContentTest { 54 55 static Robot robot; 56 static TreeTableView<Person> treeTableView; 57 static volatile Stage stage; 58 static volatile Scene scene; 59 static final int SCENE_WIDTH = 450; 60 static final int SCENE_HEIGHT = 100; 61 static CountDownLatch startupLatch; 62 63 public static void main(String[] args) { 64 TreeTableViewResizeColumnToFitContentTest test = 65 new TreeTableViewResizeColumnToFitContentTest(); 66 test.resizeColumnToFitContentTest(); 67 } 68 69 @Test 70 public void resizeColumnToFitContentTest() { 71 double colOneWidth = treeTableView.getColumns().get(0).getWidth(); 72 double colTwoWidth = treeTableView.getColumns().get(1).getWidth(); 73 double colThreeWidth = treeTableView.getColumns().get(2).getWidth(); 74 double colsWidthBeforeResize = colOneWidth + colTwoWidth + colThreeWidth; 75 double colHeaderHeight = 25; 76 double posX = scene.getWindow().getX() + treeTableView.getLayoutX() + 77 colOneWidth + colTwoWidth; 78 double posY = scene.getWindow().getY() + treeTableView.getLayoutY() + 79 colHeaderHeight / 2; 80 CountDownLatch latch = new CountDownLatch(1); 81 Platform.runLater(() -> { 82 robot.mouseMove((int) posX, (int) posY); 83 robot.mousePress(Robot.MOUSE_LEFT_BTN); 84 robot.mouseRelease(Robot.MOUSE_LEFT_BTN); 85 robot.mousePress(Robot.MOUSE_LEFT_BTN); 86 robot.mouseRelease(Robot.MOUSE_LEFT_BTN); 87 latch.countDown(); 88 }); 89 waitForLatch(latch, 5, "Timeout while waiting for mouse double click"); 90 try { 91 Thread.sleep(1000); // Delay for table resizing of table columns. 92 } catch (Exception e) { 93 fail("Thread was interrupted." + e); 94 } 95 Assert.assertTrue("resizeColumnToFitContent failed", 96 (colTwoWidth != treeTableView.getColumns().get(1).getWidth())); 97 colTwoWidth = treeTableView.getColumns().get(1).getWidth(); 98 colThreeWidth = treeTableView.getColumns().get(2).getWidth(); 99 double colsWidthAfterResize = colOneWidth + colTwoWidth + colThreeWidth; 100 Assert.assertEquals("TreeTableView.CONSTRAINED_RESIZE_POLICY ignored.", 101 colsWidthBeforeResize, colsWidthAfterResize, 0); 102 } 103 104 @BeforeClass 105 public static void initFX() { 106 startupLatch = new CountDownLatch(1); 107 new Thread(() -> Application.launch( 108 TreeTableViewResizeColumnToFitContentTest.TestApp.class, 109 (String[]) null)).start(); 110 waitForLatch(startupLatch, 10, "Timeout waiting for FX runtime to start"); 111 } 112 113 @AfterClass 114 public static void exit() { 115 Platform.runLater(() -> { 116 stage.hide(); 117 }); 118 Platform.exit(); 119 } 120 121 public static void waitForLatch(CountDownLatch latch, 122 int seconds, String msg) { 123 try { 124 if (!latch.await(seconds, TimeUnit.SECONDS)) { 125 fail(msg); 126 } 127 } catch (Exception ex) { 128 fail("Unexpected exception: " + ex); 129 } 130 } 131 132 public static class TestApp extends Application { 133 134 @Override 135 public void start(Stage primaryStage) { 136 robot = com.sun.glass.ui.Application.GetApplication().createRobot(); 137 stage = primaryStage; 138 139 treeTableView = new TreeTableView<>(); 140 TreeTableColumn<Person, String> firstNameCol 141 = new TreeTableColumn<>("First Name"); 142 143 TreeTableColumn<Person, String> lastNameCol 144 = new TreeTableColumn<>("Last Name"); 145 146 TreeTableColumn<Person, String> descriptionCol 147 = new TreeTableColumn<>("Description"); 148 149 firstNameCol.setCellValueFactory(new TreeItemPropertyValueFactory<Person, String>("firstName")); 150 descriptionCol.setCellValueFactory(new TreeItemPropertyValueFactory<Person, String>("description")); 151 lastNameCol.setCellValueFactory(new TreeItemPropertyValueFactory<Person, String>("lastName")); 152 153 treeTableView.getColumns().addAll(firstNameCol, descriptionCol, lastNameCol); 154 treeTableView.setColumnResizePolicy(TreeTableView.CONSTRAINED_RESIZE_POLICY); 155 156 Person person = new Person("John", "Currently wearing brown pants", "Doe" ); 157 TreeItem<Person> itemRoot = new TreeItem<Person>(person); 158 treeTableView.setRoot(itemRoot); 159 160 scene = new Scene(treeTableView, SCENE_WIDTH, SCENE_HEIGHT); 161 stage.setScene(scene); 162 stage.initStyle(StageStyle.UNDECORATED); 163 stage.addEventHandler(WindowEvent.WINDOW_SHOWN, e -> 164 Platform.runLater(startupLatch::countDown)); 165 stage.setAlwaysOnTop(true); 166 stage.show(); 167 } 168 } 169 170 public static final class Person { 171 172 private String firstName; 173 private String description; 174 private String lastName; 175 176 public Person(String firstName, String description, String lastName) { 177 this.firstName = firstName; 178 this.description = description; 179 this.lastName = lastName; 180 } 181 182 public String getFirstName() { 183 return firstName; 184 } 185 186 public void setFirstName(String firstName) { 187 this.firstName = firstName; 188 } 189 190 public String getLastName() { 191 return lastName; 192 } 193 194 public void setLastName(String lastName) { 195 this.lastName = lastName; 196 } 197 198 public String getDescription() { 199 return description; 200 } 201 202 public void setDescription(String description) { 203 this.description = description; 204 } 205 } 206 }