1 /* 2 * Copyright (c) 2009, 2012, 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 */ 24 package test.scenegraph.fullscreen; 25 26 27 28 import java.util.logging.Level; 29 import java.util.logging.Logger; 30 import javafx.animation.*; 31 import javafx.application.Application; 32 import javafx.beans.value.ChangeListener; 33 import javafx.beans.value.ObservableValue; 34 import javafx.event.ActionEvent; 35 import javafx.event.Event; 36 import javafx.event.EventHandler; 37 import javafx.geometry.Insets; 38 import javafx.geometry.Pos; 39 import javafx.scene.Scene; 40 import javafx.scene.control.*; 41 import javafx.scene.effect.InnerShadow; 42 import javafx.scene.input.KeyCombination; 43 import javafx.scene.input.MouseEvent; 44 import javafx.scene.layout.*; 45 import javafx.scene.paint.Color; 46 import javafx.scene.shape.Circle; 47 import javafx.scene.shape.CircleBuilder; 48 import javafx.scene.shape.LineBuilder; 49 import javafx.scene.text.Text; 50 import javafx.stage.Modality; 51 import javafx.stage.Screen; 52 import javafx.stage.Stage; 53 import javafx.util.Duration; 54 import test.javaclient.shared.Utils; 55 56 /** 57 * 58 * @author alexander 59 */ 60 public class FSTestApp extends Application { 61 62 //if stage resizable 63 private static boolean resizable = true; 64 65 66 private final StringBuilder log = new StringBuilder(); 67 68 /** 69 * @param args the command line arguments 70 */ 71 public static void main(String[] args) { 72 if((args != null) && (args.length != 0)) 73 resizable = Boolean.valueOf(args[0]); 74 75 Utils.launch(FSTestApp.class, args); 76 } 77 78 @Override 79 public void start(final Stage primaryStage) { 80 primaryStage.setTitle("FSTestApp"); 81 primaryStage.setResizable(resizable); 82 83 GridPane buttonsPane = GridPaneBuilder.create() 84 .padding(new Insets(10)) 85 .alignment(Pos.CENTER) 86 .columnConstraints(new ColumnConstraints(200), new ColumnConstraints(200)) 87 .rowConstraints(new RowConstraints(30), new RowConstraints(30), 88 new RowConstraints(30), new RowConstraints(30), 89 new RowConstraints(30)) 90 .build(); 91 92 final TextArea logTextArea = TextAreaBuilder.create() 93 .editable(false) 94 .build(); 95 96 //Timer for update logTextArea 97 Timeline updateLogTimeline = TimelineBuilder.create() 98 .keyFrames(new KeyFrame(Duration.seconds(0.1), new EventHandler<ActionEvent>() { 99 100 public void handle(ActionEvent t) { 101 logTextArea.insertText(logTextArea.getLength(), log.toString()); 102 log.delete(0, log.length()); 103 104 } 105 }, ( KeyValue[])null)) // cast null to suppress compiler warning 106 .cycleCount(-1) 107 .build(); 108 109 //<editor-fold defaultstate="collapsed" desc="Menu"> 110 MenuBar menu = MenuBarBuilder.create() 111 .menus( 112 MenuBuilder.create() 113 .text("_Menu1") 114 .onShown(new EventHandler<Event>() { 115 116 public void handle(Event t) { 117 log.append("Menu 1 Shown\n"); 118 } 119 }) 120 .onHidden(new EventHandler<Event>() { 121 122 public void handle(Event t) { 123 log.append("Menu 1 Hidden\n"); 124 } 125 }) 126 .mnemonicParsing(true) 127 .items( 128 MenuItemBuilder.create() 129 .mnemonicParsing(true) 130 .onAction(new EventHandler<ActionEvent>() { 131 132 public void handle(ActionEvent t) { 133 log.append("Menu Item 1 Action\n"); 134 } 135 }) 136 .accelerator(KeyCombination.keyCombination("ctrl+m")) 137 .text("Menu _Item 1") 138 .build(), 139 MenuItemBuilder.create() 140 .mnemonicParsing(true) 141 .text("Menu I_tem 2") 142 .build()) 143 .build(), 144 MenuBuilder.create() 145 .mnemonicParsing(true) 146 .text("M_enu2") 147 .onShown(new EventHandler<Event>() { 148 149 public void handle(Event t) { 150 log.append("Menu 2 Shown\n"); 151 } 152 }) 153 .onHidden(new EventHandler<Event>() { 154 155 public void handle(Event t) { 156 log.append("Menu 2 Hidden\n"); 157 } 158 }) 159 .items( 160 MenuItemBuilder.create() 161 .mnemonicParsing(true) 162 .text("Menu _Item 1") 163 .build(), 164 MenuItemBuilder.create() 165 .mnemonicParsing(true) 166 .text("Menu I_tem 2") 167 .build(), 168 MenuItemBuilder.create() 169 .mnemonicParsing(true) 170 .text("Menu Ite_m 3") 171 .build()) 172 .build()) 173 .useSystemMenuBar(true) 174 .build(); 175 //</editor-fold> 176 177 //<editor-fold defaultstate="collapsed" desc="Fullscreen indicator"> 178 final Circle fullscreenIndicator = 179 CircleBuilder.create() 180 .radius(6) 181 .fill(Color.RED) 182 .effect(new InnerShadow()) 183 .build(); 184 185 primaryStage.fullScreenProperty().addListener(new ChangeListener<Boolean>() { 186 187 @Override 188 public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { 189 fullscreenIndicator.setFill(newValue.booleanValue() ? Color.GREEN : Color.RED); 190 } 191 }); 192 //</editor-fold> 193 194 //<editor-fold defaultstate="collapsed" desc="Fullscreen false Button"> 195 Button setFSFalseButton = ButtonBuilder.create() 196 .text("Set fullscreen false") 197 .alignment(Pos.CENTER) 198 .prefWidth(180) 199 .onMouseClicked(new EventHandler<MouseEvent>() { 200 201 @Override 202 public void handle(MouseEvent arg0) { 203 primaryStage.setFullScreen(false); 204 } 205 }) 206 .build(); 207 208 buttonsPane.add(setFSFalseButton, 0, 0); 209 //</editor-fold> 210 211 //<editor-fold defaultstate="collapsed" desc="Fullscreen true Button"> 212 Button setFSTrueButton = ButtonBuilder.create() 213 .text("Set fullscreen true") 214 .alignment(Pos.CENTER) 215 .prefWidth(180) 216 .onMouseClicked(new EventHandler<MouseEvent>() { 217 218 @Override 219 public void handle(MouseEvent arg0) { 220 primaryStage.setFullScreen(true); 221 } 222 }) 223 .build(); 224 225 buttonsPane.add(setFSTrueButton, 1, 0); 226 //</editor-fold> 227 228 //<editor-fold defaultstate="collapsed" desc="Center Button"> 229 Button centerButton = ButtonBuilder.create() 230 .text("Center") 231 .alignment(Pos.CENTER) 232 .prefWidth(180) 233 .onMouseClicked(new EventHandler<MouseEvent>() { 234 235 @Override 236 public void handle(MouseEvent arg0) { 237 primaryStage.centerOnScreen(); 238 } 239 }) 240 .build(); 241 242 buttonsPane.add(centerButton, 0, 1); 243 //</editor-fold> 244 245 //<editor-fold defaultstate="collapsed" desc="Close Button"> 246 Button closeButton = ButtonBuilder.create() 247 .text("Close") 248 .alignment(Pos.CENTER) 249 .prefWidth(180) 250 .onMouseClicked(new EventHandler<MouseEvent>() { 251 252 @Override 253 public void handle(MouseEvent arg0) { 254 primaryStage.close(); 255 } 256 }) 257 .build(); 258 259 buttonsPane.add(closeButton, 1, 1); 260 //</editor-fold> 261 262 //<editor-fold defaultstate="collapsed" desc="Size to scene Button"> 263 Button sizeToSceneButton = ButtonBuilder.create() 264 .text("Size to scene") 265 .alignment(Pos.CENTER) 266 .prefWidth(180) 267 .onMouseClicked(new EventHandler<MouseEvent>() { 268 269 @Override 270 public void handle(MouseEvent arg0) { 271 primaryStage.sizeToScene(); 272 } 273 }) 274 .build(); 275 276 buttonsPane.add(sizeToSceneButton, 0, 2); 277 //</editor-fold> 278 279 //<editor-fold defaultstate="collapsed" desc="Show modality window Button"> 280 Button showModalityWindowButton = ButtonBuilder.create() 281 .text("Show modality window") 282 .alignment(Pos.CENTER) 283 .prefWidth(180) 284 .onMouseClicked(new EventHandler<MouseEvent>() { 285 286 @Override 287 public void handle(MouseEvent arg0) { 288 Stage modalityStage = new Stage(); 289 modalityStage.initModality(Modality.APPLICATION_MODAL); 290 modalityStage.setScene(createTestGridScene()); 291 modalityStage.setResizable(resizable); 292 modalityStage.show(); 293 } 294 }) 295 .build(); 296 297 buttonsPane.add(showModalityWindowButton, 1, 2); 298 //</editor-fold> 299 300 //<editor-fold defaultstate="collapsed" desc="Resizable Button"> 301 Button resizableButton = ButtonBuilder.create() 302 .text(resizable ? "Not resizable" : "Resizable") 303 .alignment(Pos.CENTER) 304 .prefWidth(180) 305 .onMouseClicked(new EventHandler<MouseEvent>() { 306 307 @Override 308 public void handle(MouseEvent arg0) { 309 runJVMProcess(FSTestApp.this.getClass().getName(), String.valueOf(!resizable)); 310 primaryStage.close(); 311 } 312 }).build(); 313 314 buttonsPane.add(resizableButton, 0, 3); 315 //</editor-fold> 316 317 //<editor-fold defaultstate="collapsed" desc="Opacity Slider"> 318 Slider opacitySlider = SliderBuilder.create() 319 .maxWidth(180) 320 .value(1) 321 .min(0) 322 .max(1) 323 .build(); 324 primaryStage.opacityProperty().bindBidirectional(opacitySlider.valueProperty()); 325 326 327 buttonsPane.add(opacitySlider, 1, 3); 328 //</editor-fold> 329 330 //<editor-fold defaultstate="collapsed" desc="System menu ToggleButton"> 331 ToggleButton useSystemMenuToggleButton = ToggleButtonBuilder.create() 332 .text("Use system menu") 333 .alignment(Pos.CENTER) 334 .prefWidth(180) 335 .build(); 336 337 menu.useSystemMenuBarProperty().bindBidirectional(useSystemMenuToggleButton.selectedProperty()); 338 339 buttonsPane.add(useSystemMenuToggleButton, 0, 4); 340 //</editor-fold> 341 342 VBox root = VBoxBuilder.create() 343 .children( 344 menu, 345 HBoxBuilder.create() 346 .alignment(Pos.CENTER) 347 .padding(new Insets(5)) 348 .children( 349 fullscreenIndicator, 350 new Text("Fullscreen")) 351 .build(), 352 buttonsPane, 353 logTextArea) 354 .build(); 355 356 357 primaryStage.setScene(new Scene(root, 400, 400)); 358 primaryStage.setMinHeight(400); 359 primaryStage.setMinWidth(400); 360 primaryStage.show(); 361 362 updateLogTimeline.play(); 363 } 364 365 /** 366 * Run class in new process 367 * @param className name of class 368 * @param arg run argument 369 */ 370 private void runJVMProcess(String className, String arg) { 371 try { 372 String cp = System.getProperty("java.class.path"); 373 String pathToJava = System.getProperty("java.home") + "/bin/java"; 374 375 Runtime.getRuntime().exec(new String[]{pathToJava, "-cp", cp, className, arg}); 376 } catch (Exception ex) { 377 Logger.getLogger(FSTestApp.class.getName()).log(Level.SEVERE, null, ex); 378 } 379 } 380 381 382 /** 383 * Create scene with grid. 384 * @return new scene 385 */ 386 private Scene createTestGridScene(){ 387 double height = getMaxScreenHeight(); 388 double width = getMaxScreenWidth(); 389 390 391 Pane root = PaneBuilder.create() 392 .minHeight(height) 393 .minWidth(width) 394 .build(); 395 396 for (int x = 0; x < width; x+=10) { 397 root.getChildren().add( 398 LineBuilder.create() 399 .startX(x) 400 .endX(x) 401 .startY(0) 402 .endY(height) 403 .build()); 404 } 405 406 for (int y = 0; y < height; y+=10) { 407 root.getChildren().add( 408 LineBuilder.create() 409 .startX(0) 410 .endX(width) 411 .startY(y) 412 .endY(y) 413 .build()); 414 } 415 416 return new Scene(root, 200, 200); 417 } 418 419 /** 420 * Get maximum height of all monitors. 421 * @return maximum height 422 */ 423 private double getMaxScreenHeight(){ 424 double result = 0; 425 426 for(Screen screen : Screen.getScreens()){ 427 if(screen.getBounds().getHeight() > result){ 428 result = screen.getBounds().getHeight(); 429 } 430 } 431 432 return result; 433 } 434 435 /** 436 * Get maximum width of all monitors. 437 * @return maximum width 438 */ 439 private double getMaxScreenWidth(){ 440 double result = 0; 441 442 for(Screen screen : Screen.getScreens()){ 443 if(screen.getBounds().getWidth() > result){ 444 result = screen.getBounds().getWidth(); 445 } 446 } 447 448 return result; 449 } 450 451 452 }