├── Chapter01 ├── build.xml ├── manifest.mf ├── nbproject │ ├── build-impl.xml │ ├── jfx-impl.xml │ ├── project.properties │ └── project.xml └── src │ ├── FXParams.java │ └── chapter1 │ ├── FXApplicationDemo.java │ ├── FXModality.java │ ├── HelloFX.java │ ├── StageFullScreen.java │ ├── StageStylesDemo.java │ ├── clock │ └── ClockOne.java │ └── layoutmanagers │ ├── AnchorPaneDemo.java │ ├── BorderPaneDemo.java │ ├── FlowPaneDemo.java │ ├── GridPaneDemo.java │ ├── HBoxDemo.java │ ├── StackPaneDemo.java │ └── TilePaneDemo.java ├── Chapter02 ├── build.xml ├── manifest.mf ├── nbproject │ ├── build-impl.xml │ ├── jfx-impl.xml │ ├── project.properties │ └── project.xml └── src │ └── chapter2 │ ├── clock │ └── ClockTwo.java │ ├── other │ ├── BinaryOps.java │ ├── Bounds.java │ ├── BoundsDemo.java │ ├── ButtonDemo.java │ ├── TextDemo.java │ └── Transformations.java │ ├── paint │ ├── ColorsDemo.java │ ├── GradientDemo.java │ └── ImagePatternDemo.java │ ├── shapes │ ├── AnimatedQuadCurve.java │ ├── ArcAndEllipse.java │ ├── ClosedShapes.java │ ├── CubicCurveDemo.java │ ├── PathDemo.java │ └── Polylines.java │ └── strokes │ ├── DashExamples.java │ ├── LineJoins.java │ ├── StrokeTypesDemo.java │ └── Strokes.java ├── Chapter03 ├── build.xml ├── manifest.mf ├── nbproject │ ├── UPDATED.TXT │ ├── build-impl.xml │ ├── jfx-impl.xml │ ├── jfx-impl_backup.xml │ ├── project.properties │ └── project.xml └── src │ ├── chapter3 │ ├── basics │ │ ├── BidirectionalBindingDemo.java │ │ ├── CirclePropertiesDemo.java │ │ ├── WidthBinding.java │ │ └── WidthObservable.java │ └── operations │ │ ├── ConcatBinding.java │ │ ├── Rectangles.java │ │ └── StringLengthBind.java │ ├── collections │ ├── BindLists.java │ ├── BindListsContent.java │ └── Extractor.java │ └── other │ ├── BidiConverters.java │ ├── CreateBinding.java │ └── ListenersDemo.java ├── Chapter04 ├── build.xml ├── manifest.mf ├── nbproject │ ├── build-impl.xml │ ├── jfx-impl.xml │ ├── project.properties │ └── project.xml └── src │ └── chapter4 │ ├── demo.css │ ├── demo_en.properties │ ├── demo_fr.properties │ ├── first │ ├── DemoFXML.java │ ├── FirstController.java │ └── FirstDocument.fxml │ ├── fxroot │ ├── FxRootDemo.java │ ├── MyControl.fxml │ ├── MyControl.java │ └── MyController.java │ ├── includes │ ├── FirstController.java │ ├── FirstDocument.fxml │ ├── FxmlIncludesDemo.java │ ├── MyLabel.fxml │ └── NestedController.java │ ├── locale │ ├── LocaleDemo.java │ └── LocaleDemoDoc.fxml │ ├── script │ ├── StaticDemo.java │ └── StaticDemoDoc.fxml │ └── staticdemo │ ├── ScriptDemo.java │ └── ScriptDoc.fxml ├── Chapter05 ├── build.xml ├── manifest.mf ├── nbproject │ ├── build-impl.xml │ ├── jfx-impl.xml │ ├── project.properties │ └── project.xml └── src │ └── chapter5 │ ├── app │ └── PlanetDemo.java │ ├── basics │ ├── BasicAnimation.java │ ├── CombinedAnimation.java │ ├── HandlerDemo.java │ └── InterpolatorsDemo.java │ └── transitions │ ├── ColorTransitionsDemo.java │ ├── PathTransitionDemo.java │ ├── RotateTransitionDemo.java │ ├── SequentialTransitionDemo.java │ └── TranslateTransitionDemo.java ├── Chapter06 ├── build.xml ├── manifest.mf ├── nbproject │ ├── build-impl.xml │ ├── jfx-impl.xml │ ├── project.properties │ └── project.xml └── src │ └── chapter6 │ ├── basics │ ├── FirstStyles.java │ ├── SetStyleDemo.java │ └── style.css │ ├── cssapi │ ├── Clock.java │ ├── ClockControl.java │ └── clock.css │ └── syntax │ ├── DescendancyDemo.java │ ├── InheritDemo.java │ ├── PseudoClassDemo.java │ ├── inherit-demo.css │ ├── pseudo-class-demo.css │ └── selectors-demo.css ├── Chapter07 ├── build.xml ├── manifest.mf ├── nbproject │ ├── build-impl.xml │ ├── jfx-impl.xml │ ├── project.properties │ └── project.xml └── src │ └── chapter7 │ └── resizing │ ├── FlowLayoutDemo.java │ ├── HGrowDemo.java │ ├── MinMaxSizeDemo.java │ ├── ScrollPaneDemo.java │ └── browser │ ├── AnchorsDemo.java │ ├── Controller.java │ └── browser.fxml ├── Chapter08 ├── build.xml ├── manifest.mf ├── nbproject │ ├── build-impl.xml │ ├── jfx-impl.xml │ ├── project.properties │ └── project.xml └── src │ └── chapter8 │ ├── basiceffects │ ├── BlurDemo.java │ ├── DropShadowDemo.java │ ├── InnerShadowDemo.java │ ├── ReflectionDemo.java │ ├── ShadowBorders.java │ └── ShadowDemo.java │ ├── colors │ ├── BloomGlowDemo.java │ ├── ColorAdjustDemo.java │ ├── ColorInputDemo.java │ └── SepiaToneDemo.java │ ├── combining │ ├── AllBlendModesDemo.java │ ├── BlendDiffDemo.java │ ├── BlendSrcDemo.java │ ├── LightAndDarkDemo.java │ └── ReflectionAndShadows.java │ ├── geometry │ ├── DisplacementMapDemo.java │ └── PerspectiveDemo.java │ └── light │ ├── BumpInputDemo.java │ ├── LightingDemo.java │ ├── PointLightDemo.java │ └── SpotLightDemo.java ├── Chapter09 ├── build.xml ├── manifest.mf ├── nbproject │ ├── build-impl.xml │ ├── jfx-impl.xml │ ├── project.properties │ └── project.xml └── src │ └── chapter9 │ ├── media │ ├── AudioClipDemo.java │ ├── MediaAudioDemo.java │ ├── MediaVideoDemo.java │ └── MediaVideoEffectsDemo.java │ └── web │ ├── DOMModelDemo.java │ ├── JS2JavaBridgeDemo.java │ ├── LoadWorkerDemo.java │ ├── WebEngineDemo.java │ ├── WebOverlay.java │ └── WebViewDemo.java ├── Chapter10 ├── build.xml ├── manifest.mf ├── nbproject │ ├── build-impl.xml │ ├── jfx-impl.xml │ ├── project.properties │ └── project.xml └── src │ └── chapter10 │ ├── chart │ ├── CrazyLineChartDemo.java │ ├── LineChartDemo.java │ ├── PieChartDemo.java │ └── XYChartsDemo.java │ ├── list │ ├── CheckBoxDemo.java │ ├── ChoiceBoxListCellDemo.java │ ├── CustomCelfFactoryDemo.java │ ├── ListViewDemo.java │ ├── MultiselectDemo.java │ └── TextFieldListCellDemo.java │ ├── skins │ ├── ClockControl.java │ ├── ClockDemo.java │ ├── ClockSkinHands.java │ └── ClockSkinText.java │ └── table │ ├── EditableTableViewDemo.java │ ├── ObservableChapter.java │ └── TableViewDemo.java ├── Chapter11 └── SimpleApp │ ├── build.sh │ └── src │ ├── chapterEleven │ ├── MyController.java │ ├── SecondStage.fxml │ └── SimpleApp.java │ └── module-info.java ├── Chapter12 ├── build.xml ├── manifest.mf ├── nbproject │ ├── build-impl.xml │ ├── jfx-impl.xml │ ├── project.properties │ └── project.xml └── src │ └── chapter12 │ ├── Basic3dDemo.java │ ├── EarthDemo.java │ ├── LightDemo.java │ └── MaterialBumpMapDemo.java ├── LICENSE └── README.md /Chapter01/manifest.mf: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | X-COMMENT: Main-Class will be added automatically by build 3 | 4 | -------------------------------------------------------------------------------- /Chapter01/nbproject/project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.netbeans.modules.java.j2seproject 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | Chapter1 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Chapter01/src/FXParams.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | import javafx.application.Application; 5 | import javafx.application.Platform; 6 | import javafx.scene.Scene; 7 | import javafx.scene.control.Label; 8 | import javafx.scene.layout.StackPane; 9 | import javafx.scene.layout.VBox; 10 | import javafx.stage.Stage; 11 | 12 | /** 13 | * 14 | * @author sgrinev 15 | */ 16 | public class FXParams extends Application { 17 | 18 | @Override 19 | public void start(Stage primaryStage) throws Exception { 20 | 21 | System.out.println("== Raw =="); 22 | getParameters().getRaw().forEach(System.out::println); 23 | 24 | System.out.println("== Unnamed =="); 25 | getParameters().getUnnamed().forEach(System.out::println); 26 | 27 | System.out.println("== Named =="); 28 | getParameters().getNamed().forEach((p, v) -> { System.out.println(p + "=" +v);}); 29 | 30 | // we don't need to do any UI for this demo and just exit 31 | Platform.exit(); 32 | } 33 | 34 | public static void main(String[] args) { 35 | launch(args); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /Chapter01/src/chapter1/FXApplicationDemo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter1; 5 | 6 | import javafx.application.Application; 7 | import javafx.scene.Group; 8 | import javafx.scene.Scene; 9 | import javafx.stage.Stage; 10 | 11 | /** 12 | * 13 | * @author sgrinev 14 | */ 15 | public class FXApplicationDemo extends Application { 16 | 17 | @Override 18 | public void init() { 19 | System.out.println("Before"); 20 | } 21 | 22 | @Override 23 | public void start(Stage stage) { 24 | Scene scene = new Scene(new Group(), 300, 250); 25 | stage.setTitle("Hello World!"); 26 | stage.setScene(scene); 27 | stage.show(); 28 | } 29 | 30 | public void stop() { 31 | System.out.println("After"); 32 | } 33 | 34 | public static void main(String[] args) { 35 | launch(args); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Chapter01/src/chapter1/FXModality.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter1; 5 | 6 | import javafx.application.Application; 7 | import javafx.scene.*; 8 | import javafx.stage.Modality; 9 | import javafx.stage.Stage; 10 | 11 | public class FXModality extends Application { 12 | 13 | @Override 14 | public void start(Stage stage1) { 15 | // here we create a regular window 16 | Scene scene = new Scene(new Group(), 300, 250); 17 | stage1.setTitle("Main Window"); 18 | stage1.setScene(scene); 19 | stage1.show(); 20 | 21 | // this window doesn't block mouse and keyboard events 22 | Stage stage2 = new Stage(); 23 | stage2.setTitle("I don't block anything"); 24 | stage2.initModality(Modality.NONE); 25 | stage2.show(); 26 | 27 | // this window blocks everything - you can't interact 28 | // with other windows while it's open 29 | Stage stage3 = new Stage(); 30 | stage3.setTitle("I block everything"); 31 | stage3.initModality(Modality.APPLICATION_MODAL); 32 | stage3.show(); 33 | 34 | // this window blocks only interaction with main app window (stage1) 35 | Stage stage4 = new Stage(); 36 | stage4.setTitle("I block only clicks to main window"); 37 | stage4.initOwner(stage1); 38 | stage4.initModality(Modality.WINDOW_MODAL); 39 | stage4.show(); 40 | } 41 | 42 | public static void main(String[] args) { 43 | launch(args); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Chapter01/src/chapter1/HelloFX.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter1; 5 | 6 | import javafx.application.Application; 7 | import javafx.scene.Node; 8 | import javafx.scene.Parent; 9 | import javafx.scene.Scene; 10 | import javafx.scene.control.CheckBox; 11 | import javafx.scene.layout.StackPane; 12 | import javafx.scene.paint.Color; 13 | import javafx.scene.shape.Rectangle; 14 | import javafx.stage.Stage; 15 | 16 | /** 17 | * 18 | * @author sgrinev 19 | */ 20 | public class HelloFX extends Application { 21 | 22 | @Override 23 | public void start(Stage stage) { 24 | StackPane root = new StackPane(); 25 | 26 | CheckBox node = new CheckBox("I'm ready for FX!"); 27 | Rectangle rect = new Rectangle(140, 70, Color.LIGHTGRAY); 28 | root.getChildren().addAll(rect, node); 29 | 30 | Scene scene = new Scene(root, 150, 100); 31 | 32 | stage.setScene(scene); 33 | stage.setTitle("Hello FX!"); 34 | stage.show(); 35 | 36 | traverse(root, 0); 37 | } 38 | 39 | public static void traverse(Node node, int level) { 40 | for (int i = 0; i < level; i++) { 41 | System.out.print(" "); 42 | } 43 | System.out.println(node.getClass()); 44 | if (node instanceof Parent) { 45 | Parent parent = (Parent) node; 46 | parent.getChildrenUnmodifiable().forEach(n -> traverse(n, level + 1)); 47 | } 48 | } 49 | 50 | public static void main(String[] args) { 51 | launch(args); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Chapter01/src/chapter1/StageFullScreen.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter1; 5 | 6 | import javafx.application.Application; 7 | import javafx.event.ActionEvent; 8 | import javafx.event.EventHandler; 9 | import javafx.scene.Scene; 10 | import javafx.scene.control.Button; 11 | import javafx.scene.input.KeyCode; 12 | import javafx.scene.input.KeyCodeCombination; 13 | import javafx.scene.input.KeyCombination; 14 | import javafx.scene.layout.StackPane; 15 | import javafx.stage.Stage; 16 | 17 | /** 18 | * 19 | * @author sgrinev 20 | */ 21 | public class StageFullScreen extends Application { 22 | 23 | @Override 24 | public void start(Stage primaryStage) { 25 | Button btn = new Button(); 26 | btn.setText("Say 'Hello World'"); 27 | btn.setOnAction(new EventHandler() { 28 | 29 | @Override 30 | public void handle(ActionEvent event) { 31 | System.out.println("Hello World!"); 32 | } 33 | }); 34 | 35 | StackPane root = new StackPane(); 36 | root.getChildren().add(btn); 37 | 38 | Scene scene = new Scene(root, 300, 250); 39 | 40 | primaryStage.setTitle("Hello World!"); 41 | primaryStage.setScene(scene); 42 | primaryStage.setFullScreenExitHint("Exit code is Ctrl+B"); 43 | primaryStage.setFullScreenExitKeyCombination(KeyCombination.valueOf("Ctrl+B")); 44 | primaryStage.setFullScreen(true); 45 | primaryStage.show(); 46 | KeyCodeCombination kc = new KeyCodeCombination(KeyCode.B, KeyCombination.CONTROL_DOWN); 47 | } 48 | 49 | public static void main(String[] args) { 50 | launch(args); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Chapter01/src/chapter1/StageStylesDemo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter1; 5 | 6 | import javafx.application.Application; 7 | import javafx.scene.Scene; 8 | import javafx.scene.layout.Pane; 9 | import javafx.scene.layout.StackPane; 10 | import javafx.scene.paint.Color; 11 | import javafx.scene.text.Text; 12 | import javafx.stage.Stage; 13 | import javafx.stage.StageStyle; 14 | 15 | /** 16 | * 17 | * @author sgrinev 18 | */ 19 | public class StageStylesDemo extends Application { 20 | 21 | @Override 22 | public void start(Stage primaryStage) { 23 | 24 | Pane root = new Pane(); 25 | root.setStyle("-fx-background-color: #eeeeee;"); 26 | Scene scene = new Scene(root, 300, 250); 27 | 28 | primaryStage.setTitle("Stage Styles demo"); 29 | primaryStage.setX(0); 30 | primaryStage.setY(0); 31 | primaryStage.setWidth(1300); 32 | primaryStage.setHeight(300); 33 | primaryStage.setScene(scene); 34 | primaryStage.show(); 35 | 36 | int shift = 100; 37 | for (StageStyle value : StageStyle.values()) { 38 | Stage stage = new Stage(value); 39 | stage.setX(shift); 40 | stage.setY(100); 41 | shift += 200; 42 | stage.setTitle(value.name()); 43 | Scene scene2 = new Scene(new StackPane(new Text(value.name())), 150, 100); 44 | scene2.setFill(Color.TRANSPARENT); 45 | stage.setScene(scene2); 46 | stage.show(); 47 | } 48 | } 49 | 50 | /** 51 | * @param args the command line arguments 52 | */ 53 | public static void main(String[] args) { 54 | launch(args); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Chapter01/src/chapter1/clock/ClockOne.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter1.clock; 5 | 6 | import java.text.SimpleDateFormat; 7 | import java.util.Date; 8 | import javafx.application.Application; 9 | import javafx.application.Platform; 10 | import javafx.scene.Scene; 11 | import javafx.scene.layout.BorderPane; 12 | import javafx.scene.text.Font; 13 | import javafx.scene.text.Text; 14 | import javafx.stage.Stage; 15 | import javafx.stage.StageStyle; 16 | 17 | /** 18 | * 19 | * @author sgrinev 20 | */ 21 | public class ClockOne extends Application { 22 | 23 | // we are allowed to create UI objects on non-UI thread 24 | private final Text txtTime = new Text(); 25 | 26 | private volatile boolean enough = false; 27 | 28 | Thread timer = new Thread(() -> { 29 | SimpleDateFormat dt = new SimpleDateFormat("hh:mm:ss"); 30 | // we use old-school method for the simplicity here 31 | // we'll learn how to approach timing JavaFX way in Chapter 5 32 | while (!enough) { 33 | final String time = dt.format(new Date()); 34 | Platform.runLater(() -> { 35 | // updating live UI object requires JavaFX App Thread 36 | txtTime.setText(time); 37 | }); 38 | 39 | try { 40 | // running "long" operation not on UI thread 41 | Thread.sleep(1000); 42 | } catch (InterruptedException ex) { 43 | } 44 | } 45 | }); 46 | 47 | @Override 48 | public void start(Stage stage) { 49 | BorderPane root = new BorderPane(); 50 | root.setCenter(txtTime); 51 | txtTime.setFont(Font.font("Verdana", 20)); 52 | 53 | Scene scene = new Scene(root, 200, 150); 54 | 55 | stage.initStyle(StageStyle.UTILITY); 56 | stage.setScene(scene); 57 | 58 | timer.start(); 59 | stage.show(); 60 | } 61 | 62 | @Override 63 | public void stop() { 64 | // we need to stop our working thread after closing a window 65 | // or our program will not exit 66 | enough = true; 67 | } 68 | 69 | public static void main(String[] args) { 70 | launch(args); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Chapter01/src/chapter1/layoutmanagers/AnchorPaneDemo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter1.layoutmanagers; 5 | 6 | import javafx.application.Application; 7 | import javafx.scene.Scene; 8 | import javafx.scene.layout.AnchorPane; 9 | import javafx.scene.layout.Pane; 10 | import javafx.scene.paint.Color; 11 | import javafx.scene.shape.Rectangle; 12 | import javafx.stage.Stage; 13 | 14 | /** 15 | * 16 | * @author sgrinev 17 | */ 18 | public class AnchorPaneDemo extends Application { 19 | 20 | @Override 21 | public void start(Stage primaryStage) { 22 | 23 | Rectangle rect = new Rectangle(50, 50, Color.BLUE); 24 | 25 | Pane root = new AnchorPane(rect); 26 | AnchorPane.setRightAnchor(rect, 20.); 27 | AnchorPane.setBottomAnchor(rect, 20.); 28 | 29 | Scene scene = new Scene(root, 150, 100); 30 | 31 | primaryStage.setTitle("AnchorPane"); 32 | primaryStage.setScene(scene); 33 | primaryStage.show(); 34 | } 35 | 36 | /** 37 | * @param args the command line arguments 38 | */ 39 | public static void main(String[] args) { 40 | launch(args); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /Chapter01/src/chapter1/layoutmanagers/BorderPaneDemo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter1.layoutmanagers; 5 | 6 | import javafx.application.Application; 7 | import javafx.geometry.Pos; 8 | import javafx.scene.Scene; 9 | import javafx.scene.layout.BorderPane; 10 | import javafx.scene.text.Text; 11 | import javafx.stage.Stage; 12 | 13 | /** 14 | * 15 | * @author sgrinev 16 | */ 17 | public class BorderPaneDemo extends Application { 18 | 19 | @Override 20 | public void start(Stage primaryStage) { 21 | BorderPane root = new BorderPane(); 22 | root.setRight(new Text("Right ")); 23 | root.setCenter(new Text("Center")); 24 | root.setBottom(new Text(" Bottom")); 25 | root.setLeft(new Text(" Left")); 26 | 27 | Text top = new Text("Top"); 28 | root.setTop(top); 29 | BorderPane.setAlignment(top, Pos.CENTER); 30 | root.setStyle("-fx-padding: 5px"); 31 | 32 | Scene scene = new Scene(root, 300, 250); 33 | primaryStage.setTitle("BorderPane"); 34 | primaryStage.setScene(scene); 35 | primaryStage.show(); 36 | } 37 | 38 | /** 39 | * @param args the command line arguments 40 | */ 41 | public static void main(String[] args) { 42 | launch(args); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /Chapter01/src/chapter1/layoutmanagers/FlowPaneDemo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter1.layoutmanagers; 5 | 6 | import javafx.application.Application; 7 | import javafx.scene.Scene; 8 | import javafx.scene.layout.FlowPane; 9 | import javafx.scene.paint.Color; 10 | import javafx.scene.shape.Rectangle; 11 | import javafx.stage.Stage; 12 | 13 | /** 14 | * 15 | * @author sgrinev 16 | */ 17 | public class FlowPaneDemo extends Application { 18 | 19 | @Override 20 | public void start(Stage primaryStage) { 21 | FlowPane root = new FlowPane(5, 5); 22 | 23 | for (int i = 0; i < 4; i++) { 24 | for (int j = 0; j < 4; j++) { 25 | double size = 5 + 30 * Math.random(); 26 | Rectangle rect = new Rectangle(size, size, (i + j) % 2 == 0 ? Color.RED : Color.BLUE); 27 | root.getChildren().add(rect); 28 | } 29 | 30 | } 31 | 32 | Scene scene = new Scene(root, 300, 250); 33 | 34 | primaryStage.setTitle(root.getClass().getSimpleName()); 35 | primaryStage.setScene(scene); 36 | primaryStage.show(); 37 | } 38 | 39 | /** 40 | * @param args the command line arguments 41 | */ 42 | public static void main(String[] args) { 43 | launch(args); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Chapter01/src/chapter1/layoutmanagers/GridPaneDemo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter1.layoutmanagers; 5 | 6 | import javafx.application.Application; 7 | import javafx.scene.Scene; 8 | import javafx.scene.layout.ColumnConstraints; 9 | import javafx.scene.layout.GridPane; 10 | import javafx.scene.layout.RowConstraints; 11 | import javafx.scene.paint.Color; 12 | import javafx.scene.shape.Rectangle; 13 | import javafx.stage.Stage; 14 | 15 | /** 16 | * 17 | * @author sgrinev 18 | */ 19 | public class GridPaneDemo extends Application { 20 | 21 | @Override 22 | public void start(Stage primaryStage) { 23 | 24 | GridPane root = new GridPane(); 25 | 26 | for (int i = 0; i < 5; i++) { 27 | root.getColumnConstraints().add(new ColumnConstraints(50)); 28 | root.getRowConstraints().add(new RowConstraints(50)); 29 | } 30 | 31 | for (int i = 0; i < 5; i++) { 32 | for (int j = 0; j < 5; j++) { 33 | if ((i + j) % 2 == 0) { 34 | root.add(new Rectangle(30, 30, Color.BLUE), i, j); 35 | } 36 | } 37 | } 38 | 39 | Scene scene = new Scene(root, 250, 250); 40 | 41 | primaryStage.setTitle("Hello World!"); 42 | primaryStage.setScene(scene); 43 | primaryStage.show(); 44 | } 45 | 46 | /** 47 | * @param args the command line arguments 48 | */ 49 | public static void main(String[] args) { 50 | launch(args); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /Chapter01/src/chapter1/layoutmanagers/HBoxDemo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter1.layoutmanagers; 5 | 6 | import javafx.application.Application; 7 | import javafx.geometry.Pos; 8 | import javafx.scene.Scene; 9 | import javafx.scene.layout.HBox; 10 | import javafx.scene.paint.Color; 11 | import javafx.scene.shape.Rectangle; 12 | import javafx.stage.Stage; 13 | 14 | /** 15 | * 16 | * @author sgrinev 17 | */ 18 | public class HBoxDemo extends Application { 19 | 20 | @Override 21 | public void start(Stage primaryStage) { 22 | HBox hbox = new HBox(5); 23 | hbox.setAlignment(Pos.CENTER); 24 | hbox.getChildren().addAll( 25 | new Rectangle(50, 50, Color.GREEN), 26 | new Rectangle(75, 75, Color.BLUE), 27 | new Rectangle(90, 90, Color.RED)); 28 | Scene scene = new Scene(hbox, 300, 250); 29 | 30 | primaryStage.setTitle("Hello World!"); 31 | primaryStage.setScene(scene); 32 | primaryStage.show(); 33 | } 34 | 35 | /** 36 | * @param args the command line arguments 37 | */ 38 | public static void main(String[] args) { 39 | launch(args); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /Chapter01/src/chapter1/layoutmanagers/StackPaneDemo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter1.layoutmanagers; 5 | 6 | import javafx.application.Application; 7 | import javafx.scene.Scene; 8 | import javafx.scene.layout.Pane; 9 | import javafx.scene.layout.StackPane; 10 | import javafx.scene.paint.Color; 11 | import javafx.scene.shape.Rectangle; 12 | import javafx.stage.Stage; 13 | 14 | /** 15 | * 16 | * @author sgrinev 17 | */ 18 | public class StackPaneDemo extends Application { 19 | 20 | @Override 21 | public void start(Stage primaryStage) { 22 | Pane root = new StackPane(); 23 | Rectangle red; 24 | root.getChildren().addAll( 25 | new Rectangle(50, 50, Color.GREEN), // is behind blue and invisible 26 | new Rectangle(75, 75, Color.BLUE), 27 | red = new Rectangle(90, 90, Color.RED)); 28 | red.toBack(); 29 | 30 | Scene scene = new Scene(root, 300, 250); 31 | 32 | primaryStage.setTitle("Hello World!"); 33 | primaryStage.setScene(scene); 34 | primaryStage.show(); 35 | } 36 | 37 | /** 38 | * @param args the command line arguments 39 | */ 40 | public static void main(String[] args) { 41 | launch(args); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Chapter01/src/chapter1/layoutmanagers/TilePaneDemo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter1.layoutmanagers; 5 | 6 | import javafx.application.Application; 7 | import javafx.scene.Scene; 8 | import javafx.scene.layout.TilePane; 9 | import javafx.scene.paint.Color; 10 | import javafx.scene.shape.Rectangle; 11 | import javafx.stage.Stage; 12 | 13 | /** 14 | * 15 | * @author sgrinev 16 | */ 17 | public class TilePaneDemo extends Application { 18 | 19 | @Override 20 | public void start(Stage primaryStage) { 21 | TilePane root = new TilePane(5, 5); 22 | root.setPrefColumns(4); 23 | root.setPrefRows(4); 24 | 25 | for (int i = 0; i < 4; i++) { 26 | for (int j = 0; j < 4; j++) { 27 | double size = 5 + 30 * Math.random(); 28 | Rectangle rect = new Rectangle(size, size, (i + j) % 2 == 0 ? Color.RED : Color.BLUE); 29 | root.getChildren().add(rect); 30 | } 31 | 32 | } 33 | 34 | Scene scene = new Scene(root, 300, 250); 35 | 36 | primaryStage.setTitle(root.getClass().getSimpleName()); 37 | primaryStage.setScene(scene); 38 | primaryStage.show(); 39 | } 40 | 41 | /** 42 | * @param args the command line arguments 43 | */ 44 | public static void main(String[] args) { 45 | launch(args); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /Chapter02/manifest.mf: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | X-COMMENT: Main-Class will be added automatically by build 3 | 4 | -------------------------------------------------------------------------------- /Chapter02/nbproject/project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.netbeans.modules.java.j2seproject 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | Chapter2 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Chapter02/src/chapter2/other/BinaryOps.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter2.other; 5 | 6 | import javafx.application.Application; 7 | import javafx.geometry.Insets; 8 | import javafx.geometry.Pos; 9 | import javafx.scene.Scene; 10 | import javafx.scene.layout.HBox; 11 | import javafx.scene.shape.Circle; 12 | import javafx.scene.shape.Rectangle; 13 | import javafx.scene.shape.Shape; 14 | import javafx.stage.Stage; 15 | 16 | /** 17 | * 18 | * @author sgrinev 19 | */ 20 | public class BinaryOps extends Application { 21 | 22 | @Override 23 | public void start(Stage primaryStage) { 24 | HBox root = new HBox(40); 25 | root.setPadding(new Insets(20)); 26 | root.setAlignment(Pos.CENTER); 27 | 28 | Circle circle = new Circle(30); 29 | Rectangle rect = new Rectangle(45, 45); 30 | 31 | root.getChildren().addAll( 32 | Shape.union(circle, rect), 33 | Shape.intersect(circle, rect), 34 | Shape.subtract(circle, rect) 35 | ); 36 | 37 | primaryStage.setTitle("Bezier Curves"); 38 | primaryStage.setScene(new Scene(root, 300, 250)); 39 | primaryStage.show(); 40 | } 41 | 42 | public static void main(String[] args) { 43 | launch(args); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Chapter02/src/chapter2/other/Bounds.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter2.other; 5 | 6 | import javafx.application.Application; 7 | import javafx.event.ActionEvent; 8 | import javafx.event.EventHandler; 9 | import javafx.scene.Scene; 10 | import javafx.scene.control.Button; 11 | import javafx.scene.layout.StackPane; 12 | import javafx.stage.Stage; 13 | 14 | /** 15 | * 16 | * @author sgrinev 17 | */ 18 | public class Bounds extends Application { 19 | 20 | @Override 21 | public void start(Stage primaryStage) { 22 | Button btn = new Button(); 23 | btn.setText("Say 'Hello World'"); 24 | btn.setOnAction(new EventHandler() { 25 | 26 | @Override 27 | public void handle(ActionEvent event) { 28 | System.out.println("Hello World!"); 29 | } 30 | }); 31 | 32 | StackPane root = new StackPane(); 33 | root.getChildren().add(btn); 34 | 35 | Scene scene = new Scene(root, 300, 250); 36 | 37 | primaryStage.setTitle("Hello World!"); 38 | primaryStage.setScene(scene); 39 | primaryStage.show(); 40 | } 41 | 42 | /** 43 | * @param args the command line arguments 44 | */ 45 | public static void main(String[] args) { 46 | launch(args); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /Chapter02/src/chapter2/other/ButtonDemo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter2.other; 5 | 6 | import javafx.application.Application; 7 | import javafx.event.ActionEvent; 8 | import javafx.event.EventHandler; 9 | import javafx.scene.Scene; 10 | import javafx.scene.control.Button; 11 | import javafx.scene.layout.StackPane; 12 | import javafx.scene.shape.Circle; 13 | import javafx.scene.text.Text; 14 | import javafx.stage.Stage; 15 | 16 | /** 17 | * 18 | * @author sgrinev 19 | */ 20 | public class ButtonDemo extends Application { 21 | 22 | @Override 23 | public void start(Stage primaryStage) { 24 | Button btn = new Button(); 25 | btn.setText("_Press Alt+P to fire me."); 26 | btn.setGraphic(new Circle(10)); 27 | btn.setDefaultButton(true); 28 | btn.setOnAction(new EventHandler() { 29 | 30 | @Override 31 | public void handle(ActionEvent event) { 32 | System.out.println("I was fired."); 33 | } 34 | }); 35 | 36 | StackPane root = new StackPane(); 37 | root.getChildren().addAll(btn); 38 | 39 | Scene scene = new Scene(root, 300, 250); 40 | 41 | primaryStage.setTitle("Hello World!"); 42 | primaryStage.setScene(scene); 43 | primaryStage.show(); 44 | } 45 | 46 | public static void main(String[] args) { 47 | launch(args); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /Chapter02/src/chapter2/other/TextDemo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter2.other; 5 | 6 | import javafx.application.Application; 7 | import javafx.geometry.Insets; 8 | import javafx.scene.Scene; 9 | import javafx.scene.layout.VBox; 10 | import javafx.scene.paint.Color; 11 | import javafx.scene.paint.CycleMethod; 12 | import javafx.scene.paint.LinearGradient; 13 | import javafx.scene.paint.Stop; 14 | import javafx.scene.text.Font; 15 | import javafx.scene.text.FontPosture; 16 | import javafx.scene.text.FontWeight; 17 | import javafx.scene.text.Text; 18 | import javafx.scene.text.TextFlow; 19 | import javafx.stage.Stage; 20 | 21 | /** 22 | * 23 | * @author sgrinev 24 | */ 25 | public class TextDemo extends Application { 26 | 27 | @Override 28 | public void start(Stage primaryStage) { 29 | Text txt = new Text("Hello\nJavaFX!"); 30 | txt.setFont(Font.font("Courier New", FontWeight.BOLD, FontPosture.ITALIC, 30)); 31 | 32 | Stop[] stops = new Stop[]{new Stop(0, Color.BLACK), new Stop(1, Color.DARKGRAY), new Stop(0.5, Color.ANTIQUEWHITE)}; 33 | LinearGradient gradient = new LinearGradient(50, 50, 250, 50, false, CycleMethod.NO_CYCLE, stops); 34 | txt.setFill(gradient); 35 | 36 | Text txt1 = new Text("Text1"); 37 | txt1.setFont(Font.font("Courier New", 15)); 38 | Text txt2 = new Text("Text2"); 39 | txt2.setFont(Font.font("Times New Roman", 20)); 40 | Text txt3 = new Text("Text3"); 41 | txt3.setFont(Font.font("Arial", 30)); 42 | TextFlow textFlow = new TextFlow(txt1, txt2, txt3); 43 | 44 | VBox root = new VBox(30, txt, textFlow); 45 | root.setPadding(new Insets(20)); 46 | Scene scene = new Scene(root, 300, 250); 47 | primaryStage.setTitle("Hello World!"); 48 | primaryStage.setScene(scene); 49 | primaryStage.show(); 50 | } 51 | 52 | public static void main(String[] args) { 53 | launch(args); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /Chapter02/src/chapter2/other/Transformations.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter2.other; 5 | 6 | import javafx.application.Application; 7 | import javafx.geometry.Insets; 8 | import javafx.scene.Scene; 9 | import javafx.scene.layout.StackPane; 10 | import javafx.scene.layout.TilePane; 11 | import javafx.scene.paint.Color; 12 | import javafx.scene.shape.Rectangle; 13 | import javafx.scene.transform.Rotate; 14 | import javafx.scene.transform.Shear; 15 | import javafx.scene.transform.Transform; 16 | import javafx.stage.Stage; 17 | 18 | /** 19 | * 20 | * @author sgrinev 21 | */ 22 | public class Transformations extends Application { 23 | 24 | private Rectangle addRect() { 25 | // here we create two rectangles: 26 | // one for transformation 27 | Rectangle rect = new Rectangle(20, 100, Color.DARKGRAY); 28 | // and another to demonstrate original untransformed rectangle bounds 29 | Rectangle rectOrig = new Rectangle(20, 100); 30 | rectOrig.setFill(Color.TRANSPARENT); 31 | rectOrig.setStroke(Color.BLACK); 32 | 33 | StackPane pane = new StackPane(rect, rectOrig); 34 | root.getChildren().add(pane); 35 | 36 | return rect; 37 | } 38 | 39 | TilePane root = new TilePane(50,50); 40 | 41 | @Override 42 | public void start(Stage primaryStage) { 43 | Rectangle rect1 = addRect(); 44 | rect1.setRotate(30); 45 | 46 | Rectangle rect2 = addRect(); 47 | rect2.setTranslateY(20); 48 | 49 | Rectangle rect3 = addRect(); 50 | rect3.setScaleX(2); 51 | 52 | Rectangle rect4 = addRect(); 53 | rect4.getTransforms().add(new Shear(0.3, 0)); 54 | 55 | Rectangle rect5 = addRect(); 56 | Transform t1 = new Shear(0.3, 0); 57 | Transform t2 = new Rotate(-15); 58 | rect5.getTransforms().add(t1.createConcatenation(t2)); 59 | 60 | root.setPadding(new Insets(50)); 61 | primaryStage.setTitle("Hello World!"); 62 | primaryStage.setScene(new Scene(root, 500, 250)); 63 | primaryStage.show(); 64 | } 65 | 66 | public static void main(String[] args) { 67 | launch(args); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /Chapter02/src/chapter2/paint/ColorsDemo.java: -------------------------------------------------------------------------------- 1 | package chapter2.paint; 2 | 3 | import javafx.application.Application; 4 | import javafx.scene.Scene; 5 | import javafx.scene.layout.Pane; 6 | import javafx.scene.paint.Color; 7 | import javafx.scene.shape.Circle; 8 | import javafx.stage.Stage; 9 | 10 | /** 11 | * 12 | * @author sgrinev 13 | */ 14 | public class ColorsDemo extends Application { 15 | 16 | @Override 17 | public void start(Stage primaryStage) { 18 | 19 | Pane root = new Pane(); 20 | root.getChildren().addAll( 21 | // RED, opacity 0.3 22 | new Circle(150, 80, 70, Color.rgb(255, 0, 0, 0.3)), 23 | // GREEN, opacity 0.3 24 | new Circle(100, 180, 70, Color.hsb(120, 1.0, 1.0, 0.3)), 25 | // BLUE, opacity 0.3 26 | new Circle(200, 180, 70, Color.web("0x0000FF", 0.3)) 27 | ); 28 | 29 | Scene scene = new Scene(root, 300, 280); 30 | 31 | primaryStage.setTitle("Color Demo"); 32 | primaryStage.setScene(scene); 33 | primaryStage.show(); 34 | } 35 | 36 | /** 37 | * @param args the command line arguments 38 | */ 39 | public static void main(String[] args) { 40 | launch(args); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /Chapter02/src/chapter2/paint/GradientDemo.java: -------------------------------------------------------------------------------- 1 | package chapter2.paint; 2 | 3 | import javafx.application.Application; 4 | import javafx.scene.Scene; 5 | import javafx.scene.canvas.Canvas; 6 | import javafx.scene.canvas.GraphicsContext; 7 | import javafx.scene.layout.StackPane; 8 | import javafx.scene.paint.Color; 9 | import javafx.scene.paint.CycleMethod; 10 | import javafx.scene.paint.LinearGradient; 11 | import javafx.scene.paint.Stop; 12 | import javafx.scene.shape.Rectangle; 13 | import javafx.scene.text.Text; 14 | import javafx.stage.Stage; 15 | 16 | /** 17 | * 18 | * @author sgrinev 19 | */ 20 | public class GradientDemo extends Application { 21 | 22 | @Override 23 | public void start(Stage primaryStage) { 24 | 25 | Rectangle rect = new Rectangle(300, 200); 26 | 27 | Stop[] stops = new Stop[]{ 28 | new Stop(0, Color.BLACK), 29 | new Stop(1, Color.ANTIQUEWHITE)}; 30 | LinearGradient lg1 = new LinearGradient(0, 0, 300, 200, false, CycleMethod.NO_CYCLE, stops); 31 | rect.setFill(lg1); 32 | 33 | StackPane root = new StackPane(); 34 | root.getChildren().addAll(rect); 35 | 36 | Scene scene = new Scene(root, 400, 300); 37 | 38 | primaryStage.setTitle("Gradient"); 39 | primaryStage.setScene(scene); 40 | primaryStage.show(); 41 | } 42 | 43 | /** 44 | * @param args the command line arguments 45 | */ 46 | public static void main(String[] args) { 47 | launch(args); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /Chapter02/src/chapter2/paint/ImagePatternDemo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter2.paint; 5 | 6 | import javafx.application.Application; 7 | import javafx.scene.Scene; 8 | import javafx.scene.image.Image; 9 | import javafx.scene.layout.StackPane; 10 | import javafx.scene.paint.ImagePattern; 11 | import javafx.scene.shape.Circle; 12 | import javafx.stage.Stage; 13 | 14 | /** 15 | * 16 | * @author sgrinev 17 | */ 18 | public class ImagePatternDemo extends Application { 19 | 20 | @Override 21 | public void start(Stage primaryStage) { 22 | 23 | StackPane root = new StackPane(); 24 | root.getChildren().add( 25 | new Circle(100, 26 | new ImagePattern( 27 | new Image("https://upload.wikimedia.org/wikipedia/commons/3/3f/Chimpanzee_congo_painting.jpg")))); 28 | 29 | Scene scene = new Scene(root, 300, 250); 30 | 31 | primaryStage.setTitle("Hello World!"); 32 | primaryStage.setScene(scene); 33 | primaryStage.show(); 34 | } 35 | 36 | /** 37 | * @param args the command line arguments 38 | */ 39 | public static void main(String[] args) { 40 | launch(args); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /Chapter02/src/chapter2/shapes/AnimatedQuadCurve.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter2.shapes; 5 | 6 | import javafx.animation.KeyFrame; 7 | import javafx.animation.KeyValue; 8 | import javafx.animation.Timeline; 9 | import javafx.application.Application; 10 | import javafx.scene.Scene; 11 | import javafx.scene.layout.Pane; 12 | import javafx.scene.paint.Color; 13 | import javafx.scene.shape.Line; 14 | import javafx.scene.shape.Polyline; 15 | import javafx.scene.shape.QuadCurve; 16 | import javafx.stage.Stage; 17 | import javafx.util.Duration; 18 | 19 | /** 20 | * 21 | * @author sgrinev 22 | */ 23 | public class AnimatedQuadCurve extends Application { 24 | 25 | @Override 26 | public void start(Stage primaryStage) { 27 | QuadCurve quad = new QuadCurve(); 28 | quad.setStartX(50); 29 | quad.setStartY(200); 30 | quad.setEndX(250); 31 | quad.setEndY(200); 32 | quad.setControlX(275); 33 | quad.setControlY(20); 34 | quad.setFill(Color.DARKGRAY); 35 | 36 | Polyline lines = new Polyline( 37 | quad.getStartX(), quad.getStartY(), 38 | quad.getControlX(), quad.getControlY(), 39 | quad.getEndX(), quad.getEndY()); 40 | 41 | Line tangent = new Line(quad.getStartX(), quad.getStartY(), quad.getControlX(), quad.getControlY()); 42 | tangent.setStroke(Color.RED); 43 | tangent.setStrokeWidth(2); 44 | 45 | Timeline moveTangent = new Timeline( 46 | new KeyFrame(Duration.seconds(5), 47 | new KeyValue(tangent.startXProperty(), quad.getControlX()), 48 | new KeyValue(tangent.startYProperty(), quad.getControlY()), 49 | new KeyValue(tangent.endXProperty(), quad.getEndX()), 50 | new KeyValue(tangent.endYProperty(), quad.getEndY()) 51 | )); 52 | moveTangent.setCycleCount(Timeline.INDEFINITE); 53 | 54 | Pane root = new Pane(); 55 | root.getChildren().addAll(quad, lines, tangent); 56 | primaryStage.setTitle("Bezier Curves Demo"); 57 | primaryStage.setScene(new Scene(root, 300, 250)); 58 | primaryStage.show(); 59 | moveTangent.play(); 60 | } 61 | 62 | public static void main(String[] args) { 63 | launch(args); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /Chapter02/src/chapter2/shapes/ArcAndEllipse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter2.shapes; 5 | 6 | import javafx.application.Application; 7 | import javafx.geometry.Insets; 8 | import javafx.scene.Scene; 9 | import javafx.scene.layout.HBox; 10 | import javafx.scene.paint.Color; 11 | import javafx.scene.shape.Arc; 12 | import javafx.scene.shape.CubicCurve; 13 | import javafx.scene.shape.Ellipse; 14 | import javafx.stage.Stage; 15 | 16 | /** 17 | * 18 | * @author sgrinev 19 | */ 20 | public class ArcAndEllipse extends Application { 21 | 22 | @Override 23 | public void start(Stage primaryStage) { 24 | Ellipse ellipse = new Ellipse(); 25 | ellipse.setRadiusX(60); 26 | ellipse.setRadiusY(40); 27 | ellipse.setFill(Color.DARKGREY); 28 | 29 | Arc arc = new Arc(); 30 | arc.setRadiusX(60); 31 | arc.setRadiusY(40); 32 | arc.setFill(Color.DARKGREY); 33 | arc.setStartAngle(45); 34 | arc.setLength(180); 35 | 36 | HBox root = new HBox(20); 37 | root.setPadding(new Insets(20)); 38 | root.getChildren().addAll(ellipse, arc); 39 | primaryStage.setTitle("Arc and Ellipse"); 40 | primaryStage.setScene(new Scene(root, 300, 250)); 41 | primaryStage.show(); 42 | } 43 | 44 | public static void main(String[] args) { 45 | launch(args); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /Chapter02/src/chapter2/shapes/ClosedShapes.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter2.shapes; 5 | 6 | import javafx.application.Application; 7 | import javafx.geometry.Insets; 8 | import javafx.geometry.Pos; 9 | import javafx.scene.Scene; 10 | import javafx.scene.layout.HBox; 11 | import javafx.scene.paint.Color; 12 | import javafx.scene.shape.Circle; 13 | import javafx.scene.shape.Ellipse; 14 | import javafx.scene.shape.Polygon; 15 | import javafx.scene.shape.Rectangle; 16 | import javafx.stage.Stage; 17 | 18 | /** 19 | * 20 | * @author sgrinev 21 | */ 22 | public class ClosedShapes extends Application { 23 | 24 | @Override 25 | public void start(Stage primaryStage) { 26 | Rectangle rect = new Rectangle(50, 50); 27 | rect.setArcHeight(10); 28 | rect.setArcWidth(10); 29 | rect.setFill(Color.DARKGREY); 30 | 31 | Circle circle = new Circle(50); 32 | circle.setFill(Color.DARKGREY); 33 | 34 | Ellipse ellipse = new Ellipse(); 35 | ellipse.setRadiusX(60); 36 | ellipse.setRadiusY(40); 37 | ellipse.setFill(Color.DARKGREY); 38 | 39 | Polygon polygon = new Polygon(); 40 | polygon.setFill(Color.DARKGREY); 41 | polygon.getPoints().addAll( 42 | 0.0, 0.0, 43 | 50.0, 30.0, 44 | 10.0, 60.0); 45 | 46 | HBox hbox = new HBox(20); 47 | hbox.setPadding(new Insets(20)); 48 | hbox.setAlignment(Pos.CENTER); 49 | hbox.getChildren().addAll(rect, circle, ellipse, polygon); 50 | 51 | primaryStage.setTitle("Closed Shapes"); 52 | primaryStage.setScene(new Scene(hbox, 500, 150)); 53 | primaryStage.show(); 54 | } 55 | 56 | public static void main(String[] args) { 57 | launch(args); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /Chapter02/src/chapter2/shapes/CubicCurveDemo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter2.shapes; 5 | 6 | import javafx.application.Application; 7 | import javafx.scene.Scene; 8 | import javafx.scene.layout.Pane; 9 | import javafx.scene.paint.Color; 10 | import javafx.scene.shape.CubicCurve; 11 | import javafx.scene.shape.Polyline; 12 | import javafx.stage.Stage; 13 | 14 | /** 15 | * 16 | * @author sgrinev 17 | */ 18 | public class CubicCurveDemo extends Application { 19 | 20 | @Override 21 | public void start(Stage primaryStage) { 22 | CubicCurve cubic = new CubicCurve(); 23 | cubic.setStartX(50.0); 24 | cubic.setStartY(200.0); 25 | cubic.setControlX1(75.0); 26 | cubic.setControlY1(30.0); 27 | cubic.setControlX2(135.0); 28 | cubic.setControlY2(170.0); 29 | cubic.setEndX(250.0); 30 | cubic.setEndY(190.0); 31 | cubic.setFill(Color.DARKGRAY); 32 | 33 | Polyline lines = new Polyline( 34 | cubic.getStartX(), cubic.getStartY(), 35 | cubic.getControlX1(), cubic.getControlY1(), 36 | cubic.getControlX2(), cubic.getControlY2(), 37 | cubic.getEndX(), cubic.getEndY()); 38 | 39 | Pane root = new Pane(); 40 | root.getChildren().addAll(cubic, lines); 41 | primaryStage.setTitle("Cubic Curve"); 42 | primaryStage.setScene(new Scene(root, 300, 250)); 43 | primaryStage.show(); 44 | } 45 | 46 | public static void main(String[] args) { 47 | launch(args); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /Chapter02/src/chapter2/shapes/PathDemo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter2.shapes; 5 | 6 | import javafx.application.Application; 7 | import static javafx.application.Application.launch; 8 | import javafx.geometry.Insets; 9 | import javafx.scene.Scene; 10 | import javafx.scene.layout.HBox; 11 | import javafx.scene.paint.Color; 12 | import javafx.scene.shape.ArcTo; 13 | import javafx.scene.shape.ClosePath; 14 | import javafx.scene.shape.HLineTo; 15 | import javafx.scene.shape.MoveTo; 16 | import javafx.scene.shape.Path; 17 | import javafx.scene.shape.SVGPath; 18 | import javafx.scene.shape.VLineTo; 19 | import javafx.stage.Stage; 20 | 21 | /** 22 | * 23 | * @author sgrinev 24 | */ 25 | public class PathDemo extends Application { 26 | 27 | @Override 28 | public void start(Stage primaryStage) { 29 | 30 | ArcTo arcTo = new ArcTo(); // ArcTo is set separately due to its complexity 31 | arcTo.setRadiusX(250); 32 | arcTo.setRadiusY(90); 33 | arcTo.setX(50); 34 | arcTo.setY(100); 35 | arcTo.setSweepFlag(true); 36 | System.out.println(arcTo.getXAxisRotation()); 37 | 38 | Path path = new Path( 39 | new MoveTo(0, 0), 40 | new HLineTo(50), 41 | arcTo, 42 | new VLineTo(150), 43 | new HLineTo(0), 44 | new ClosePath() 45 | ); 46 | 47 | SVGPath svgPath = new SVGPath(); 48 | svgPath.setContent("M0,0 H50 A250,90 0 0,1 50,100 V150 H0 Z"); 49 | // M - move, H - horizontal line, A - arc, V - vertical line, Z - close path 50 | svgPath.setFill(Color.DARKGREY); 51 | 52 | HBox root = new HBox(30, path, svgPath); 53 | root.setPadding(new Insets(20)); 54 | 55 | primaryStage.setTitle("Paths"); 56 | primaryStage.setScene(new Scene(root, 300, 250)); 57 | primaryStage.show(); 58 | } 59 | 60 | public static void main(String[] args) { 61 | launch(args); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Chapter02/src/chapter2/shapes/Polylines.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter2.shapes; 5 | 6 | import javafx.application.Application; 7 | import javafx.collections.FXCollections; 8 | import javafx.geometry.Insets; 9 | import javafx.scene.Scene; 10 | import javafx.scene.layout.HBox; 11 | import javafx.scene.paint.Color; 12 | import javafx.scene.shape.Polygon; 13 | import javafx.scene.shape.Polyline; 14 | import javafx.stage.Stage; 15 | 16 | /** 17 | * 18 | * @author sgrinev 19 | */ 20 | public class Polylines extends Application { 21 | 22 | @Override 23 | public void start(Stage primaryStage) { 24 | 25 | Polyline polyline = new Polyline(); 26 | polyline.getPoints().addAll( 27 | 0.0, 0.0, 28 | 50.0, 30.0, 29 | 10.0, 60.0); 30 | 31 | Polyline polyline2 = new Polyline(); 32 | polyline2.getPoints().addAll(polyline.getPoints()); 33 | polyline2.setFill(Color.DARKGRAY); 34 | 35 | Polygon polygon = new Polygon(); 36 | polygon.getPoints().addAll(polyline.getPoints()); 37 | polygon.setFill(Color.DARKGRAY); 38 | polygon.setStroke(Color.BLACK); 39 | 40 | HBox root = new HBox(30); 41 | root.setPadding(new Insets(20)); 42 | root.getChildren().addAll(polyline, polyline2, polygon); 43 | 44 | primaryStage.setTitle("Hello World!"); 45 | primaryStage.setScene(new Scene(root, 300, 250)); 46 | primaryStage.show(); 47 | } 48 | 49 | /** 50 | * @param args the command line arguments 51 | */ 52 | public static void main(String[] args) { 53 | launch(args); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /Chapter02/src/chapter2/strokes/DashExamples.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter2.strokes; 5 | 6 | import javafx.application.Application; 7 | import javafx.geometry.Insets; 8 | import javafx.scene.Scene; 9 | import javafx.scene.layout.VBox; 10 | import javafx.scene.paint.Color; 11 | import javafx.scene.shape.Line; 12 | import javafx.scene.shape.StrokeLineCap; 13 | import javafx.stage.Stage; 14 | 15 | /** 16 | * 17 | * @author sgrinev 18 | */ 19 | public class DashExamples extends Application { 20 | 21 | private VBox root = new VBox(50); 22 | 23 | private Line addLine() { 24 | Line line = new Line(50, 0, 250, 0); 25 | line.setStrokeWidth(10); 26 | line.setStroke(Color.DARKGRAY); 27 | line.getStrokeDashArray().addAll(30.0, 15.0); 28 | root.getChildren().add(line); 29 | return line; 30 | } 31 | 32 | @Override 33 | public void start(Stage primaryStage) { 34 | root.setPadding(new Insets(30)); 35 | 36 | addLine().setStrokeLineCap(StrokeLineCap.SQUARE); 37 | 38 | addLine().setStrokeLineCap(StrokeLineCap.BUTT); 39 | 40 | addLine().setStrokeLineCap(StrokeLineCap.ROUND); 41 | 42 | Line line = addLine(); 43 | line.setStrokeLineCap(StrokeLineCap.SQUARE); 44 | line.setStrokeDashOffset(20); 45 | 46 | primaryStage.setTitle("Dashes"); 47 | primaryStage.setScene(new Scene(root, 300, 350)); 48 | primaryStage.show(); 49 | } 50 | 51 | public static void main(String[] args) { 52 | launch(args); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /Chapter02/src/chapter2/strokes/LineJoins.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter2.strokes; 5 | 6 | import javafx.application.Application; 7 | import static javafx.application.Application.launch; 8 | import javafx.geometry.Insets; 9 | import javafx.scene.Scene; 10 | import javafx.scene.layout.FlowPane; 11 | import javafx.scene.layout.VBox; 12 | import javafx.scene.paint.Color; 13 | import javafx.scene.shape.ClosePath; 14 | import javafx.scene.shape.HLineTo; 15 | import javafx.scene.shape.LineTo; 16 | import javafx.scene.shape.MoveTo; 17 | import javafx.scene.shape.Path; 18 | import javafx.scene.shape.StrokeLineJoin; 19 | import javafx.scene.text.Text; 20 | import javafx.stage.Stage; 21 | 22 | /** 23 | * 24 | * @author sgrinev 25 | */ 26 | public class LineJoins extends Application { 27 | 28 | private Path newPath() { 29 | Path path = new Path( 30 | new MoveTo(0, 0), new HLineTo(100), 31 | new LineTo(70, 30), new ClosePath()); 32 | path.setStroke(Color.DARKGRAY); 33 | path.setStrokeWidth(10); 34 | return path; 35 | } 36 | 37 | @Override 38 | public void start(Stage primaryStage) { 39 | 40 | FlowPane root = new FlowPane(20, 40); 41 | root.setPadding(new Insets(20)); 42 | for (StrokeLineJoin value : StrokeLineJoin.values()) { 43 | Path path = newPath(); 44 | path.setStrokeLineJoin(value); 45 | root.getChildren().add(new VBox(10, new Text(value.name()), path)); 46 | } 47 | 48 | primaryStage.setTitle("Dashes"); 49 | primaryStage.setScene(new Scene(root, 400, 250)); 50 | primaryStage.show(); 51 | } 52 | 53 | public static void main(String[] args) { 54 | launch(args); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /Chapter02/src/chapter2/strokes/StrokeTypesDemo.java: -------------------------------------------------------------------------------- 1 | package chapter2.strokes; 2 | 3 | import java.util.function.Supplier; 4 | import javafx.application.Application; 5 | import javafx.geometry.Insets; 6 | import javafx.scene.Scene; 7 | import javafx.scene.layout.HBox; 8 | import javafx.scene.layout.StackPane; 9 | import javafx.scene.layout.VBox; 10 | import javafx.scene.paint.Color; 11 | import javafx.scene.shape.Rectangle; 12 | import javafx.scene.shape.StrokeType; 13 | import javafx.scene.text.Text; 14 | import javafx.stage.Stage; 15 | 16 | /** 17 | * 18 | * @author sgrinev 19 | */ 20 | public class StrokeTypesDemo extends Application { 21 | 22 | @Override 23 | public void start(Stage primaryStage) { 24 | 25 | HBox hbox = new HBox(10); 26 | hbox.setPadding(new Insets(20)); 27 | 28 | // a lambda factory to show it's the same rectangle all the time 29 | Supplier newRect = () -> new Rectangle(50, 50, Color.LIGHTGRAY); 30 | hbox.getChildren().add(new VBox(5, new Text("NONE"), newRect.get())); 31 | 32 | for (StrokeType type : StrokeType.values()) { 33 | Rectangle rect = newRect.get(); 34 | rect.setStrokeType(type); 35 | rect.setStroke(Color.BLACK); 36 | rect.setStrokeWidth(10); 37 | 38 | hbox.getChildren().add(new VBox(5, new Text(type.toString()), rect)); 39 | } 40 | 41 | primaryStage.setTitle("Hello StrokeTypes!"); 42 | primaryStage.setScene(new Scene(new StackPane(hbox), 300, 250)); 43 | primaryStage.show(); 44 | } 45 | 46 | public static void main(String[] args) { 47 | launch(args); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /Chapter02/src/chapter2/strokes/Strokes.java: -------------------------------------------------------------------------------- 1 | package chapter2.strokes; 2 | 3 | import javafx.application.Application; 4 | import javafx.scene.Scene; 5 | import javafx.scene.layout.StackPane; 6 | import javafx.scene.paint.Color; 7 | import javafx.scene.shape.Rectangle; 8 | import javafx.scene.shape.StrokeLineCap; 9 | import javafx.scene.shape.StrokeLineJoin; 10 | import javafx.scene.shape.StrokeType; 11 | import javafx.stage.Stage; 12 | 13 | /** 14 | * 15 | * @author sgrinev 16 | */ 17 | public class Strokes extends Application { 18 | 19 | @Override 20 | public void start(Stage primaryStage) { 21 | Rectangle shape = new Rectangle(400, 100); 22 | shape.setFill(Color.WHITE); 23 | 24 | shape.setStroke(Color.RED); 25 | shape.setStrokeWidth(10); 26 | shape.setStrokeType(StrokeType.CENTERED); 27 | 28 | shape.setStrokeDashOffset(20); 29 | shape.getStrokeDashArray().addAll(100.0, 50.0); 30 | shape.setStrokeLineCap(StrokeLineCap.BUTT); 31 | shape.setStrokeLineJoin(StrokeLineJoin.MITER); 32 | shape.setStrokeMiterLimit(0); 33 | 34 | StackPane root = new StackPane(); 35 | root.getChildren().add(shape); 36 | 37 | Scene scene = new Scene(root, 600, 250); 38 | 39 | primaryStage.setTitle("Hello World!"); 40 | primaryStage.setScene(scene); 41 | primaryStage.show(); 42 | } 43 | 44 | /** 45 | * @param args the command line arguments 46 | */ 47 | public static void main(String[] args) { 48 | launch(args); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /Chapter03/manifest.mf: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | X-COMMENT: Main-Class will be added automatically by build 3 | 4 | -------------------------------------------------------------------------------- /Chapter03/nbproject/UPDATED.TXT: -------------------------------------------------------------------------------- 1 | ===================================== 2 | Project Chapter3 build script updated 3 | ===================================== 4 | 5 | Project build script file jfx-impl.xml in nbproject sub-directory has not been recognized 6 | as compliant with this version of NetBeans JavaFX support module. To ensure correct 7 | and complete functionality within this NetBeans installation the script file has been 8 | backed up to jfx-impl_backup.xml and then updated to the currently supported state. 9 | 10 | FX Project build script auto-update may be triggered on project open either after 11 | NetBeans installation update or by manual changes in jfx-impl.xml. Please note that 12 | changing jfx-impl.xml manually is not recommended. Any build customization code should 13 | be placed only in build.xml in project root directory. 14 | 15 | Remark: The auto-update mechanism can be disabled by setting property 16 | javafx.disable.autoupdate=true 17 | Automatic opening of this notification when project files are updated can be disabled by setting property 18 | javafx.disable.autoupdate.notification=true 19 | (in build.properties, private.properties or project.properties). 20 | 21 | Remark: Files nbproject/jfx-impl_backup*.xml and this file nbproject/UPDATED.TXT 22 | are not used when building the project and can be freely deleted. 23 | 24 | -------------------------------------------------------------------------------- /Chapter03/nbproject/project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.netbeans.modules.java.j2seproject 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | Chapter3 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Chapter03/src/chapter3/basics/BidirectionalBindingDemo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter3.basics; 5 | 6 | import javafx.application.Application; 7 | import javafx.geometry.Insets; 8 | import javafx.geometry.Orientation; 9 | import javafx.geometry.Pos; 10 | import javafx.scene.Scene; 11 | import javafx.scene.control.Label; 12 | import javafx.scene.control.Slider; 13 | import javafx.scene.layout.VBox; 14 | import javafx.stage.Stage; 15 | 16 | /** 17 | * 18 | * @author sgrinev 19 | */ 20 | public class BidirectionalBindingDemo extends Application { 21 | 22 | @Override 23 | public void start(Stage stage) { 24 | Slider s1 = new Slider(0, 100, 40); 25 | Slider s2 = new Slider(0, 100, 40); 26 | s2.setOrientation(Orientation.VERTICAL); 27 | s1.valueProperty().bindBidirectional(s2.valueProperty()); 28 | 29 | VBox root = new VBox(5, s1, s2); 30 | root.setAlignment(Pos.CENTER); 31 | root.setPadding(new Insets(20)); 32 | 33 | stage.setScene(new Scene(root, 200, 150)); 34 | stage.show(); 35 | 36 | // keep in mind that isBound() doesn't work for bidirectional binding 37 | System.out.println(s1.valueProperty().isBound()); // false 38 | System.out.println(s2.valueProperty().isBound()); // false 39 | } 40 | 41 | public static void main(String[] args) { 42 | launch(args); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /Chapter03/src/chapter3/basics/CirclePropertiesDemo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter3.basics; 5 | 6 | import javafx.application.Application; 7 | import javafx.beans.value.ChangeListener; 8 | import javafx.beans.value.ObservableValue; 9 | import javafx.scene.Scene; 10 | import javafx.scene.control.Slider; 11 | import javafx.scene.layout.Pane; 12 | import javafx.scene.paint.Color; 13 | import javafx.scene.shape.Circle; 14 | import javafx.stage.Stage; 15 | 16 | /** 17 | * 18 | * @author sgrinev 19 | */ 20 | public class CirclePropertiesDemo extends Application { 21 | 22 | @Override 23 | public void start(Stage primaryStage) { 24 | Pane root = new Pane(); 25 | 26 | Circle circle = new Circle(150, 150, 40, Color.ANTIQUEWHITE); 27 | circle.setStroke(Color.BLACK); 28 | 29 | Slider sliderRadius = new Slider(0, 100, 40); 30 | sliderRadius.relocate(80, 20); 31 | sliderRadius.setShowTickLabels(true); 32 | sliderRadius.setMajorTickUnit(20); 33 | 34 | circle.radiusProperty().bind(sliderRadius.valueProperty()); 35 | 36 | Slider sliderStrokeWidth = new Slider(0, 10, 2); 37 | sliderStrokeWidth.setShowTickLabels(true); 38 | sliderStrokeWidth.setMajorTickUnit(2); 39 | sliderStrokeWidth.relocate(80, 50); 40 | 41 | circle.strokeWidthProperty().bind(sliderStrokeWidth.valueProperty()); 42 | 43 | root.getChildren().addAll(sliderRadius, circle, sliderStrokeWidth); 44 | 45 | Scene scene = new Scene(root, 300, 250); 46 | 47 | primaryStage.setTitle("Hello Binding!"); 48 | primaryStage.setScene(scene); 49 | primaryStage.show(); 50 | } 51 | 52 | public static void main(String[] args) { 53 | launch(args); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /Chapter03/src/chapter3/basics/WidthBinding.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter3.basics; 5 | 6 | import javafx.application.Application; 7 | import javafx.scene.Scene; 8 | import javafx.scene.control.Label; 9 | import javafx.scene.layout.StackPane; 10 | import javafx.stage.Stage; 11 | 12 | /** 13 | * 14 | * @author sgrinev 15 | */ 16 | public class WidthBinding extends Application { 17 | 18 | @Override 19 | public void start(Stage stage) { 20 | Label label = new Label(); 21 | 22 | label.textProperty().bind(stage.widthProperty().asString()); 23 | 24 | stage.setScene(new Scene(new StackPane(label), 200, 150)); 25 | stage.show(); 26 | } 27 | 28 | public static void main(String[] args) { 29 | launch(args); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Chapter03/src/chapter3/basics/WidthObservable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter3.basics; 5 | 6 | import javafx.application.Application; 7 | import javafx.beans.value.ChangeListener; 8 | import javafx.beans.value.ObservableValue; 9 | import javafx.scene.Scene; 10 | import javafx.scene.control.Label; 11 | import javafx.scene.layout.StackPane; 12 | import javafx.stage.Stage; 13 | 14 | /** 15 | * 16 | * @author sgrinev 17 | */ 18 | public class WidthObservable extends Application { 19 | 20 | @Override 21 | public void start(Stage stage) { 22 | Label lblWidth = new Label(); 23 | 24 | stage.widthProperty().addListener(new ChangeListener() { 25 | @Override 26 | public void changed(ObservableValue observable, Number oldValue, Number newValue) { 27 | lblWidth.setText(newValue.toString()); 28 | } 29 | }); 30 | 31 | stage.setScene(new Scene(new StackPane(lblWidth), 200, 150)); 32 | stage.show(); 33 | } 34 | 35 | public static void main(String[] args) { 36 | launch(args); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Chapter03/src/chapter3/operations/ConcatBinding.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter3.operations; 5 | 6 | import javafx.application.Application; 7 | import javafx.beans.binding.Bindings; 8 | import javafx.scene.Scene; 9 | import javafx.scene.control.Label; 10 | import javafx.scene.layout.StackPane; 11 | import javafx.stage.Stage; 12 | 13 | /** 14 | * 15 | * @author sgrinev 16 | */ 17 | public class ConcatBinding extends Application { 18 | 19 | @Override 20 | public void start(Stage stage) { 21 | Label label = new Label(); 22 | 23 | label.textProperty().bind( 24 | stage.widthProperty().asString() // property one 25 | .concat(" : ") // concatting with a string constant 26 | .concat(stage.heightProperty()) // concatting with a property 2 27 | ); 28 | 29 | label.textProperty().unbind(); 30 | label.textProperty().bind( 31 | // Bindings.concat(stage.widthProperty(), " : ", stage.heightProperty()) 32 | Bindings.format("Window size is %1$.0fx%2$.0f", stage.widthProperty(), stage.heightProperty()) 33 | ); 34 | 35 | stage.setScene(new Scene(new StackPane(label), 200, 150)); 36 | stage.show(); 37 | } 38 | 39 | public static void main(String[] args) { 40 | launch(args); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Chapter03/src/chapter3/operations/Rectangles.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter3.operations; 5 | 6 | import javafx.application.Application; 7 | import javafx.beans.binding.Bindings; 8 | import javafx.beans.binding.NumberBinding; 9 | import javafx.scene.Scene; 10 | import javafx.scene.layout.Pane; 11 | import javafx.scene.paint.Color; 12 | import javafx.scene.shape.Rectangle; 13 | import javafx.stage.Stage; 14 | 15 | /** 16 | * 17 | * @author sgrinev 18 | */ 19 | public class Rectangles extends Application { 20 | 21 | @Override 22 | public void start(Stage stage) { 23 | Pane root = new Pane(); 24 | 25 | final int count = 7; //number of rectangles 26 | 27 | // version 1 28 | // NumberBinding minSide = Bindings 29 | // .min(root.heightProperty(), root.widthProperty()) 30 | // .divide(count); 31 | 32 | // version 2 33 | NumberBinding minSide = Bindings 34 | .when(root.heightProperty().lessThan(root.widthProperty()) ) 35 | .then( root.heightProperty() ) 36 | .otherwise( root.widthProperty() ) 37 | .divide(count); 38 | 39 | for (int x = 0; x < count; x++) { 40 | for (int y = 0; y < count; y++) { 41 | Rectangle rectangle = new Rectangle(0, 0, Color.LIGHTGRAY); 42 | 43 | rectangle.xProperty().bind(minSide.multiply(x)); 44 | rectangle.yProperty().bind(minSide.multiply(y)); 45 | 46 | rectangle.heightProperty().bind(minSide.subtract(2)); 47 | rectangle.widthProperty().bind(rectangle.heightProperty()); 48 | root.getChildren().add(rectangle); 49 | } 50 | } 51 | 52 | stage.setScene(new Scene(root, 500, 500)); 53 | stage.show(); 54 | } 55 | 56 | public static void main(String[] args) { 57 | launch(args); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Chapter03/src/chapter3/operations/StringLengthBind.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package chapter3.operations; 5 | 6 | import javafx.application.Application; 7 | import javafx.beans.binding.Bindings; 8 | import javafx.geometry.Pos; 9 | import javafx.scene.Scene; 10 | import javafx.scene.control.Label; 11 | import javafx.scene.control.TextField; 12 | import javafx.scene.layout.HBox; 13 | import javafx.stage.Stage; 14 | 15 | /** 16 | * 17 | * @author sgrinev 18 | */ 19 | public class StringLengthBind extends Application { 20 | 21 | @Override 22 | public void start(Stage stage) { 23 | TextField textField = new TextField(); 24 | Label lblLength = new Label(); 25 | /* 26 | lblLength.textProperty().bind( 27 | textField.textProperty() 28 | .length() // this length returns IntegerBinding, not just an integer 29 | .asString() // so you can keep observing it and use binding methods 30 | ); 31 | */ 32 | lblLength.textProperty().bind( 33 | Bindings.concat("Count: ", textField.textProperty().length())); 34 | 35 | HBox root = new HBox(20, textField, lblLength); 36 | root.setAlignment(Pos.CENTER); 37 | stage.setScene(new Scene(root, 250, 100)); 38 | stage.show(); 39 | } 40 | 41 | public static void main(String[] args) { 42 | launch(args); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Chapter03/src/collections/BindLists.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package collections; 5 | 6 | import javafx.application.Application; 7 | import javafx.scene.Scene; 8 | import javafx.scene.control.Button; 9 | import javafx.scene.control.ListView; 10 | import javafx.scene.layout.BorderPane; 11 | import javafx.stage.Stage; 12 | 13 | /** 14 | * 15 | * @author sgrinev 16 | */ 17 | public class BindLists extends Application { 18 | 19 | @Override 20 | public void start(Stage stage) { 21 | ListView listView = new ListView<>(); 22 | listView.getItems().addAll("1", "2", "abc"); 23 | 24 | ListView listView2 = new ListView<>(); 25 | listView2.itemsProperty().bind(listView.itemsProperty()); 26 | 27 | Button button = new Button("add"); 28 | button.setOnAction((e)->listView.getItems().add("Item " + listView.getItems().size())); 29 | 30 | BorderPane root = new BorderPane(); 31 | root.setLeft(listView); 32 | root.setRight(listView2); 33 | root.setBottom(button); 34 | 35 | stage.setScene(new Scene(root, 500, 250)); 36 | stage.show(); 37 | } 38 | 39 | public static void main(String[] args) { 40 | launch(args); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Chapter03/src/collections/BindListsContent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package collections; 5 | 6 | import java.util.Random; 7 | import javafx.application.Application; 8 | import javafx.application.Platform; 9 | import javafx.beans.Observable; 10 | import javafx.beans.binding.Bindings; 11 | import javafx.beans.property.SimpleStringProperty; 12 | import javafx.beans.property.StringProperty; 13 | import javafx.collections.FXCollections; 14 | import javafx.collections.ObservableList; 15 | import javafx.scene.Scene; 16 | import javafx.scene.control.Button; 17 | import javafx.scene.control.ListView; 18 | import javafx.scene.layout.BorderPane; 19 | import javafx.scene.layout.HBox; 20 | import javafx.stage.Stage; 21 | 22 | /** 23 | * 24 | * @author sgrinev 25 | */ 26 | public class BindListsContent extends Application { 27 | 28 | @Override 29 | public void start(Stage stage) { 30 | ListView listView = new ListView<>(); 31 | StringContainer sc = new StringContainer("1"); 32 | listView.getItems().addAll(sc, new StringContainer("22"), new StringContainer("bob")); 33 | 34 | ListView listView2 = new ListView<>(); 35 | listView2.itemsProperty().bind(listView.itemsProperty()); 36 | 37 | BorderPane root = new BorderPane(); 38 | root.setLeft(listView); 39 | root.setRight(listView2); 40 | 41 | Button button = new Button("add"); 42 | button.setOnAction((e)->listView.getItems().add(new StringContainer("Item " + listView.getItems().size()))); 43 | root.setBottom(button); 44 | 45 | Scene scene = new Scene(root, 500, 250); 46 | 47 | stage.setTitle("Hello World!"); 48 | stage.setScene(scene); 49 | stage.show(); 50 | listView.getItems().add(new StringContainer("new")); 51 | } 52 | 53 | public static void main(String[] args) { 54 | launch(args); 55 | } 56 | 57 | private static class StringContainer { 58 | StringProperty content = new SimpleStringProperty(); 59 | 60 | public StringContainer(String txt) { 61 | content.setValue(txt); 62 | } 63 | 64 | @Override 65 | public String toString() { 66 | return content.getValue(); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Chapter03/src/collections/Extractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Packt Publishing Ltd, 2017-2018 3 | */ 4 | package collections; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import javafx.application.Application; 9 | import javafx.beans.Observable; 10 | import javafx.beans.property.IntegerProperty; 11 | import javafx.beans.property.SimpleIntegerProperty; 12 | import javafx.collections.FXCollections; 13 | import javafx.collections.ListChangeListener; 14 | import javafx.collections.ObservableList; 15 | import javafx.geometry.Pos; 16 | import javafx.scene.Scene; 17 | import javafx.scene.control.Button; 18 | import javafx.scene.control.Label; 19 | import javafx.scene.layout.HBox; 20 | import javafx.stage.Stage; 21 | 22 | /** 23 | * 24 | * @author sgrinev 25 | */ 26 | public class Extractor extends Application { 27 | 28 | @Override 29 | public void start(Stage stage) { 30 | // Lets have a list of Buttons 31 | List