/* * Copyright (c) 2016 by Gerrit Grunwald * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package eu.hansolo; import eu.hansolo.medusa.*; import eu.hansolo.medusa.Clock; import eu.hansolo.medusa.Clock.ClockSkinType; import eu.hansolo.medusa.Gauge.NeedleSize; import eu.hansolo.medusa.Gauge.ScaleDirection; import eu.hansolo.medusa.Gauge.SkinType; import eu.hansolo.medusa.GaugeDesign.GaugeBackground; import eu.hansolo.medusa.Marker.MarkerType; import javafx.animation.AnimationTimer; import javafx.application.Application; import javafx.collections.ObservableList; import javafx.geometry.Insets; import javafx.geometry.Orientation; import javafx.scene.Node; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.layout.Background; import javafx.scene.layout.BackgroundFill; import javafx.scene.layout.ColumnConstraints; import javafx.scene.layout.CornerRadii; import javafx.scene.layout.GridPane; import javafx.scene.layout.RowConstraints; import javafx.scene.paint.Color; import javafx.scene.paint.Stop; import javafx.stage.Stage; import java.time.*; import java.util.Random; /** * Created by hansolo on 11.12.15. */ public class OverviewDemo extends Application { private static final Random RND = new Random(); private static final double MIN_CELL_SIZE = 80; private static final double PREF_CELL_SIZE = 120; private static final double MAX_CELL_SIZE = 150; private static int noOfNodes = 0; private FGauge framedGauge1; private Gauge gauge1; private FGauge framedGauge2; private Gauge gauge2; private Gauge gauge3; private Gauge gauge4; private Gauge gauge5; private Gauge gauge6; private Gauge gauge7; private Gauge gauge8; private Gauge gauge9; private Gauge gauge10; private Gauge gauge11; private Gauge gauge12; private Gauge gauge13; private Gauge gauge14; private Gauge gauge15; private Gauge gauge16; private Gauge gauge17; private Gauge gauge18; private Gauge gauge19; private Gauge gauge20; private Gauge gauge21; private Gauge gauge22; private Gauge gauge23; private Gauge gauge24; private Gauge gauge25; private Gauge gauge26; private Gauge gauge27; private Gauge gauge28; private Gauge gauge29; private Gauge gauge30; private Gauge gauge31; private Clock clock1; private Clock clock2; private Clock clock3; private Clock clock4; private Clock clock5; private Clock clock6; private Clock clock7; private Clock clock8; private Clock clock9; private Clock clock10; private Clock clock11; private Clock clock12; private long lastTimerCall; private AnimationTimer timer; @Override public void init() { gauge1 = GaugeBuilder.create() .minValue(0) .maxValue(1) .tickLabelDecimals(1) .decimals(2) .autoScale(true) .animated(true) //.backgroundPaint(Color.TRANSPARENT) //.borderPaint(Color.LIGHTGRAY) //.knobColor(Color.rgb(0, 90, 120)) .shadowsEnabled(true) //.tickLabelColor(Color.rgb(0, 175, 248)) //.ledColor(Color.rgb(0, 175, 248)) .ledVisible(true) .ledBlinking(true) .sectionsVisible(true) .sections(new Section(0.5, 0.75, Color.rgb(139, 195, 102, 0.5))) .areasVisible(true) .areas(new Section(0.75, 1.0, Color.rgb(234, 83, 79, 0.5))) .majorTickMarkColor(Color.MAGENTA) //.minorTickMarkColor(Color.rgb(0, 175, 248)) .majorTickMarkType(TickMarkType.TRAPEZOID) .mediumTickMarkType(TickMarkType.DOT) .minorTickMarkType(TickMarkType.LINE) .tickLabelOrientation(TickLabelOrientation.ORTHOGONAL) .tickMarkSections(new Section(0.25, 0.5, Color.rgb(241, 161, 71))) .tickMarkSectionsVisible(true) .markers(new Marker(0.5, "", Color.CYAN, MarkerType.TRIANGLE)) .markersVisible(true) //.majorTickMarksVisible(true) //.minorTickMarksVisible(true) .tickLabelLocation(TickLabelLocation.INSIDE) //.tickLabelsVisible(true) .tickLabelSections(new Section(0.1, 0.3, Color.rgb(0, 175, 248))) //.tickLabelSectionsVisible(true) .title("Title") //.titleColor(Color.rgb(223, 223, 223)) .unit("Unit") .lcdDesign(LcdDesign.SECTIONS) .lcdVisible(true) .lcdFont(LcdFont.STANDARD) //.unitColor(Color.rgb(223, 223, 223)) //.valueColor(Color.rgb(223, 223, 223)) .needleSize(NeedleSize.THICK) .build(); gauge2 = GaugeBuilder.create() .minValue(0) .maxValue(10) .animated(true) .autoScale(true) .shadowsEnabled(true) .ledColor(Color.rgb(250, 50, 0)) .gradientBarEnabled(true) .gradientBarStops(new Stop(0.0, Color.rgb(0, 0, 255, 0.7)), new Stop(0.5, Color.rgb(0, 200, 255, 0.7)), new Stop(1.0, Color.rgb(0, 255, 0, 0.7))) .majorTickMarkType(TickMarkType.TRAPEZOID) .majorTickMarksVisible(true) .mediumTickMarkType(TickMarkType.TRAPEZOID) .mediumTickMarksVisible(true) .minorTickMarkType(TickMarkType.LINE) .minorTickMarksVisible(false) .tickLabelsVisible(true) .tickLabelOrientation(TickLabelOrientation.HORIZONTAL) .tickLabelLocation(TickLabelLocation.INSIDE) .title("Title") .unit("Unit") .foregroundBaseColor(Gauge.BRIGHT_COLOR) .build(); gauge3 = GaugeBuilder.create() .skinType(SkinType.SIMPLE) .sections(new Section(0, 16.66666, "0", Color.web("#11632f")), new Section(16.66666, 33.33333, "1", Color.web("#36843d")), new Section(33.33333, 50.0, "2", Color.web("#67a328")), new Section(50.0, 66.66666, "3", Color.web("#80b940")), new Section(66.66666, 83.33333, "4", Color.web("#95c262")), new Section(83.33333, 100.0, "5", Color.web("#badf8d"))) .sectionsVisible(true) .title("Simple") .threshold(50) .animated(true) .build(); gauge4 = GaugeBuilder.create() .skinType(SkinType.BULLET_CHART) .sections(new Section(0, 16.66666, "0", Color.web("#11632f")), new Section(16.66666, 33.33333, "1", Color.web("#36843d")), new Section(33.33333, 50.0, "2", Color.web("#67a328")), new Section(50.0, 66.66666, "3", Color.web("#80b940")), new Section(66.66666, 83.33333, "4", Color.web("#95c262")), new Section(83.33333, 100.0, "5", Color.web("#badf8d"))) .title("BulletChart") .unit("US$ in thousands") .threshold(50) .orientation(Orientation.VERTICAL) .animated(true) .titleColor(Color.WHITE) .unitColor(Color.WHITE) .tickLabelColor(Color.WHITE) .tickMarkColor(Color.WHITE) .build(); gauge5 = GaugeBuilder.create() .skinType(SkinType.DASHBOARD) .animated(true) .title("Dashboard") .unit("\u00B0C") .maxValue(40) .barColor(Color.CRIMSON) .valueColor(Color.WHITE) .titleColor(Color.WHITE) .unitColor(Color.WHITE) .thresholdVisible(true) .threshold(35) .shadowsEnabled(true) .gradientBarEnabled(true) .gradientBarStops(new Stop(0.00, Color.BLUE), new Stop(0.25, Color.CYAN), new Stop(0.50, Color.LIME), new Stop(0.75, Color.YELLOW), new Stop(1.00, Color.RED)) .build(); gauge6 = GaugeBuilder.create() .skinType(SkinType.SPACE_X) .animated(true) .decimals(0) .title("SpaceX") .unit("km/h") .maxValue(30000) .threshold(25000) .build(); gauge7 = GaugeBuilder.create() .skinType(SkinType.AMP) .prefSize(250, 210) .minValue(-1) .maxValue(1) .tickLabelDecimals(1) .decimals(2) .startFromZero(true) .title("Amp") .unit("db") .sections(new Section(80, 100, Color.CRIMSON)) .sectionsVisible(true) .animated(true) .build(); gauge8 = GaugeBuilder.create() .skinType(SkinType.MODERN) .prefSize(400, 400) .sections(new Section(85, 90, "", Color.rgb(204, 0, 0, 0.5)), new Section(90, 95, "", Color.rgb(204, 0, 0, 0.75)), new Section(95, 100, "", Color.rgb(204, 0, 0))) .sectionTextVisible(true) .title("MODERN") .unit("UNIT") .threshold(85) .thresholdVisible(true) .animated(true) .build(); gauge9 = GaugeBuilder.create() .minValue(-1) .maxValue(2) .tickLabelDecimals(1) .autoScale(true) .animated(true) .startAngle(0) .angleRange(270) .threshold(0.5) .thresholdVisible(true) .majorTickMarkType(TickMarkType.TRAPEZOID) .mediumTickMarkType(TickMarkType.TRAPEZOID) .tickLabelColor(Color.WHITE) .tickMarkColor(Color.WHITE) .titleColor(Color.WHITE) .subTitleColor(Color.WHITE) .unitColor(Color.WHITE) .zeroColor(Color.LIGHTSKYBLUE) .lcdVisible(true) .lcdDesign(LcdDesign.FLAT_CUSTOM) .title("Title") .subTitle("SubTitle") .unit("Unit") .interactive(true) .buttonTooltipText("Test") .needleSize(NeedleSize.THIN) .tickLabelLocation(TickLabelLocation.OUTSIDE) .onButtonPressed(event -> System.out.println("Button pressed")) .onButtonReleased(event -> System.out.println("Button released")) .scaleDirection(ScaleDirection.COUNTER_CLOCKWISE) .sectionsVisible(true) .sections(new Section(0, 1, Color.rgb(200, 150, 0, 0.5))) .areasVisible(true) .highlightAreas(true) .areas(new Section(1.5, 2, Color.rgb(200, 0, 0, 0.1), Color.rgb(255, 0, 0))) .markersVisible(true) //.markersInterActive(true) .markers(new Marker(1.75, Color.LIME)) .needleColor(Color.CYAN) .build(); gauge10 = GaugeBuilder.create() .skinType(SkinType.FLAT) .title("Flat") .unit("Unit") .foregroundBaseColor(Color.WHITE) .animated(true) .build(); gauge11 = GaugeBuilder.create() .skinType(SkinType.SLIM) .animated(true) .maxValue(10000) .decimals(0) .unit("STEPS") .build(); gauge12 = GaugeBuilder.create() .skinType(SkinType.KPI) .foregroundBaseColor(Color.WHITE) .needleColor(Color.WHITE) .animated(true) .threshold(75) .title("TITLE") .build(); gauge13 = GaugeBuilder.create() .skinType(SkinType.INDICATOR) .animated(true) .build(); gauge14 = GaugeBuilder.create() .skinType(SkinType.QUARTER) .animated(true) .foregroundBaseColor(Color.WHITE) .build(); gauge15 = GaugeBuilder.create() .skinType(SkinType.HORIZONTAL) .animated(true) .foregroundBaseColor(Color.WHITE) .build(); gauge16 = GaugeBuilder.create() .skinType(SkinType.VERTICAL) .animated(true) .foregroundBaseColor(Color.WHITE) .build(); gauge17 = GaugeBuilder.create() .skinType(SkinType.LCD) .animated(true) .title("Temperature") .subTitle("Office") .unit("\u00B0C") .lcdDesign(LcdDesign.BLUE_LIGHTBLUE2) .thresholdVisible(true) .threshold(25) .build(); gauge18 = GaugeBuilder.create() .skinType(SkinType.TINY) .animated(true) .minValue(0) .sections(new Section(0, 33, Color.rgb(0, 200, 0, 0.75)), new Section(33, 66, Color.rgb(200, 200, 0, 0.75)), new Section(66, 100, Color.rgb(200, 0, 0, 0.75))) .build(); gauge19 = GaugeBuilder.create() .skinType(SkinType.BATTERY) .animated(true) .sectionsVisible(true) .sections(new Section(0, 10, Color.rgb(200, 0, 0, 0.8)), new Section(10, 30, Color.rgb(200, 200, 0, 0.8)), new Section(30, 100, Color.rgb(0, 200, 0, 0.8))) .build(); gauge20 = GaugeBuilder.create() .skinType(SkinType.LEVEL) .title("Capacity") .titleColor(Color.WHITE) .animated(true) .gradientBarEnabled(true) .gradientBarStops(new Stop(0.0, Color.RED), new Stop(0.25, Color.ORANGE), new Stop(0.5, Color.YELLOW), new Stop(0.75, Color.YELLOWGREEN), new Stop(1.0, Color.LIME)) .build(); gauge21 = GaugeBuilder.create() .skinType(SkinType.LINEAR) .title("Linear") .orientation(Orientation.HORIZONTAL) .sectionsVisible(true) .foregroundBaseColor(Color.WHITE) .barColor(Color.LIGHTSKYBLUE) .sections(new Section(0, 20, Color.BLUE), new Section(80, 100, Color.RED)) .build(); gauge22 = GaugeBuilder.create() .skinType(SkinType.DIGITAL) .foregroundBaseColor(Color.rgb(0, 222, 249)) .barColor(Color.rgb(0, 222, 249)) .title("SLIM") .unit("UNIT") .animated(true) .build(); gauge23 = GaugeBuilder.create() .skinType(SkinType.SIMPLE_DIGITAL) .foregroundBaseColor(Color.rgb(0, 249, 222)) .barColor(Color.rgb(0, 249, 222)) .unit("KPH") .animated(true) .build(); gauge24 = GaugeBuilder.create() .skinType(SkinType.SECTION) .needleColor(Color.ORANGE) .minValue(0) .maxValue(105) .animated(true) .highlightSections(true) .sections( SectionBuilder.create() .start(0) .stop(15) .text("EXCELLENT") .color(Color.rgb(223, 223, 223)) .highlightColor(Color.rgb(18, 158, 81)) .textColor(Gauge.DARK_COLOR) .build(), SectionBuilder.create() .start(15) .stop(30) .text("VERY\nGOOD") .color(Color.rgb(223, 223, 223)) .highlightColor(Color.rgb(151, 208, 77)) .textColor(Gauge.DARK_COLOR) .build(), SectionBuilder.create() .start(30) .stop(45) .text("GOOD") .color(Color.rgb(223, 223, 223)) .highlightColor(Color.rgb(197, 223, 0)) .textColor(Gauge.DARK_COLOR) .build(), SectionBuilder.create() .start(45) .stop(60) .text("FAIRLY\nGOOD") .color(Color.rgb(223, 223, 223)) .highlightColor(Color.rgb(251, 245, 0)) .textColor(Gauge.DARK_COLOR) .build(), SectionBuilder.create() .start(60) .stop(75) .text("AVERAGE") .color(Color.rgb(223, 223, 223)) .highlightColor(Color.rgb(247, 206, 0)) .textColor(Gauge.DARK_COLOR) .build(), SectionBuilder.create() .start(75) .stop(90) .text("BELOW\nAVERAGE") .color(Color.rgb(223, 223, 223)) .highlightColor(Color.rgb(227, 124, 1)) .textColor(Gauge.DARK_COLOR) .build(), SectionBuilder.create() .start(90) .stop(105) .text("POOR") .color(Color.rgb(223, 223, 223)) .highlightColor(Color.rgb(223, 49, 23)) .textColor(Gauge.DARK_COLOR) .build()) .build(); gauge25 = GaugeBuilder.create() .skinType(SkinType.BAR) .barColor(Color.rgb(237, 22, 72)) .valueColor(Color.WHITE) .unitColor(Color.WHITE) .unit("KPH") .animated(true) .build(); gauge26 = GaugeBuilder.create() .skinType(SkinType.WHITE) .unit("") .build(); gauge27 = GaugeBuilder.create() .skinType(SkinType.CHARGE) .build(); GridPane.setColumnSpan(gauge27, 2); gauge28 = GaugeBuilder.create() .skinType(SkinType.SIMPLE_SECTION) .title("Title") .unit("unit") .titleColor(Color.WHITE) .unitColor(Color.WHITE) .valueColor(Color.WHITE) .sections(new Section(0, 33, Color.LIME), new Section(33, 66, Color.YELLOW), new Section(66, 100, Color.CRIMSON)) .build(); gauge29 = GaugeBuilder.create() .skinType(SkinType.TILE_KPI) .threshold(75) .animated(true) .build(); gauge30 = GaugeBuilder.create() .skinType(SkinType.TILE_TEXT_KPI) .animated(true) .build(); gauge31 = GaugeBuilder.create() .skinType(SkinType.TILE_SPARK_LINE) .averageVisible(true) .build(); clock1 = ClockBuilder.create() .skinType(ClockSkinType.YOTA2) .sectionsVisible(true) .sections(new TimeSection(LocalTime.of(8, 0, 0), LocalTime.of(12, 0, 0), Color.rgb(0, 200, 0, 0.5)), new TimeSection(LocalTime.of(13, 0, 0), LocalTime.of(17, 0, 0), Color.rgb(0, 200, 0, 0.5))) .running(true) .build(); clock2 = ClockBuilder.create() .skinType(ClockSkinType.LCD) .lcdDesign(LcdDesign.DARKBLUE) .title("Muenster") .titleVisible(true) .secondsVisible(true) .alarmsEnabled(true) .dateVisible(true) .running(true) .build(); clock3 = ClockBuilder.create() .skinType(ClockSkinType.PEAR) .running(true) .build(); clock4 = ClockBuilder.create() .skinType(ClockSkinType.PLAIN) .areasVisible(true) .areas(new TimeSection(LocalTime.of(9, 0, 0), LocalTime.of(12, 0, 0), Color.rgb(255, 0, 255, 0.3))) .running(true) .build(); clock5 = ClockBuilder.create() .skinType(ClockSkinType.DB) .backgroundPaint(Color.WHITE) .running(true) .build(); clock6 = ClockBuilder.create() .skinType(ClockSkinType.FAT) .backgroundPaint(Color.WHITE) .hourTickMarkColor(Color.rgb(200, 200, 200)) .minuteTickMarkColor(Color.rgb(200, 200, 200)) .tickLabelColor(Color.rgb(200, 200, 200)) .running(true) .build(); clock7 = ClockBuilder.create() .skinType(ClockSkinType.ROUND_LCD) .hourColor(Color.rgb(38, 166, 154)) .minuteColor(Color.rgb(77, 182, 172)) .secondColor(Color.rgb(128, 203, 196)) .textColor(Color.rgb(128, 203, 196)) .dateColor(Color.rgb(128, 203, 196)) .running(true) .build(); clock8 = ClockBuilder.create() .skinType(ClockSkinType.SLIM) .running(true) .build(); clock9 = ClockBuilder.create() .skinType(ClockSkinType.DIGITAL) .running(true) .textColor(Color.WHITE) .dateColor(Color.LIGHTGRAY) .build(); clock10 = ClockBuilder.create() .skinType(ClockSkinType.DESIGN) .running(true) .build(); clock11 = ClockBuilder.create() .skinType(ClockSkinType.INDUSTRIAL) .running(true) .build(); clock12 = ClockBuilder.create() .skinType(ClockSkinType.TILE) .running(true) .build(); framedGauge1 = new FGauge(gauge1, GaugeDesign.ENZO, GaugeBackground.DARK_GRAY); framedGauge2 = new FGauge(gauge2, GaugeDesign.METAL); lastTimerCall = System.nanoTime(); timer = new AnimationTimer() { @Override public void handle(long now) { if (now > lastTimerCall + 3_000_000_000l) { framedGauge1.getGauge().setValue(RND.nextDouble() * gauge1.getRange() + gauge1.getMinValue()); framedGauge2.getGauge().setValue(RND.nextDouble() * gauge2.getRange() + gauge2.getMinValue()); gauge3.setValue(RND.nextDouble() * gauge3.getRange() + gauge3.getMinValue()); gauge4.setValue(RND.nextDouble() * gauge4.getRange() + gauge4.getMinValue()); gauge5.setValue(RND.nextDouble() * gauge5.getRange() + gauge5.getMinValue()); gauge6.setValue(RND.nextDouble() * gauge6.getRange() + gauge6.getMinValue()); gauge7.setValue(RND.nextDouble() * gauge7.getRange() + gauge7.getMinValue()); gauge8.setValue(RND.nextDouble() * gauge8.getRange() + gauge8.getMinValue()); gauge9.setValue(RND.nextDouble() * gauge9.getRange() + gauge9.getMinValue()); gauge10.setValue(RND.nextDouble() * gauge10.getRange() + gauge10.getMinValue()); gauge11.setValue(RND.nextDouble() * gauge11.getRange() + gauge11.getMinValue()); gauge12.setValue(RND.nextDouble() * gauge12.getRange() + gauge12.getMinValue()); gauge13.setValue(RND.nextDouble() * gauge13.getRange() + gauge13.getMinValue()); gauge14.setValue(RND.nextDouble() * gauge14.getRange() + gauge14.getMinValue()); gauge15.setValue(RND.nextDouble() * gauge15.getRange() + gauge15.getMinValue()); gauge16.setValue(RND.nextDouble() * gauge16.getRange() + gauge16.getMinValue()); gauge17.setValue(RND.nextDouble() * gauge17.getRange() + gauge17.getMinValue()); gauge18.setValue(RND.nextDouble() * gauge18.getRange() + gauge18.getMinValue()); gauge19.setValue(RND.nextDouble() * gauge19.getRange() + gauge19.getMinValue()); gauge20.setValue(RND.nextDouble() * gauge20.getRange() + gauge20.getMinValue()); gauge21.setValue(RND.nextDouble() * gauge21.getRange() + gauge21.getMinValue()); gauge22.setValue(RND.nextDouble() * gauge22.getRange() + gauge22.getMinValue()); gauge23.setValue(RND.nextDouble() * gauge23.getRange() + gauge23.getMinValue()); gauge24.setValue(RND.nextDouble() * gauge24.getRange() + gauge24.getMinValue()); gauge25.setValue(RND.nextDouble() * gauge25.getRange() + gauge25.getMinValue()); gauge26.setValue(RND.nextDouble() * gauge26.getRange() + gauge26.getMinValue()); gauge27.setValue(RND.nextDouble() * gauge27.getRange() + gauge27.getMinValue()); gauge28.setValue(RND.nextDouble() * gauge28.getRange() + gauge28.getMinValue()); gauge29.setValue(RND.nextDouble() * gauge29.getRange() + gauge29.getMinValue()); gauge30.setValue(RND.nextDouble() * gauge30.getRange() + gauge30.getMinValue()); gauge31.setValue(RND.nextDouble() * gauge31.getRange() + gauge31.getMinValue()); lastTimerCall = now; } } }; } @Override public void start(Stage stage) { GridPane pane = new GridPane(); pane.add(framedGauge1, 0, 0); pane.add(framedGauge2, 1, 0); pane.add(gauge3, 2, 0); pane.add(gauge4, 3, 0); pane.add(gauge5, 4, 0); pane.add(clock1, 5, 0); pane.add(clock5, 6, 0); pane.add(gauge22, 7, 0); pane.add(gauge29, 8, 0); pane.add(gauge6, 0, 1); pane.add(gauge7, 1, 1); pane.add(gauge8, 2, 1); pane.add(gauge9, 3, 1); pane.add(gauge10, 4, 1); pane.add(clock2, 5, 1); pane.add(gauge21, 6, 1); pane.add(gauge23, 7, 1); pane.add(gauge30, 8, 1); pane.add(gauge11, 0, 2); pane.add(gauge12, 1, 2); pane.add(gauge13, 2, 2); pane.add(gauge14, 3, 2); pane.add(gauge15, 4, 2); pane.add(clock3, 5, 2); pane.add(clock6, 6, 2); pane.add(clock8, 7, 2); pane.add(gauge31, 8, 2); pane.add(gauge16, 0, 3); pane.add(gauge17, 1, 3); pane.add(gauge18, 2, 3); pane.add(gauge19, 3, 3); pane.add(gauge20, 4, 3); pane.add(clock4, 5, 3); pane.add(clock7, 6, 3); pane.add(gauge24, 7, 3); pane.add(clock12, 8, 3); pane.add(gauge25, 0, 4); pane.add(gauge26, 1, 4); pane.add(gauge27, 2, 4); pane.add(gauge28, 4, 4); pane.add(clock9, 5, 4); pane.add(clock10, 6, 4); pane.add(clock11, 7, 4); pane.setHgap(10); pane.setVgap(10); pane.setPadding(new Insets(10)); for (int i = 0 ; i < 9 ; i++) { pane.getColumnConstraints().add(new ColumnConstraints(MIN_CELL_SIZE, PREF_CELL_SIZE, MAX_CELL_SIZE)); } for (int i = 0 ; i < 5 ; i++) { pane.getRowConstraints().add(new RowConstraints(MIN_CELL_SIZE, PREF_CELL_SIZE, MAX_CELL_SIZE)); } pane.setBackground(new Background(new BackgroundFill(Color.rgb(90, 90, 90), CornerRadii.EMPTY, Insets.EMPTY))); Scene scene = new Scene(pane); stage.setTitle("Medusa Gauges and Clocks"); stage.setScene(scene); stage.show(); timer.start(); // Calculate number of nodes calcNoOfNodes(pane); System.out.println(noOfNodes + " Nodes in SceneGraph"); } @Override public void stop() { System.exit(0); } // ******************** Misc ********************************************** private static void calcNoOfNodes(Node node) { if (node instanceof Parent) { if (((Parent) node).getChildrenUnmodifiable().size() != 0) { ObservableList<Node> tempChildren = ((Parent) node).getChildrenUnmodifiable(); noOfNodes += tempChildren.size(); for (Node n : tempChildren) { calcNoOfNodes(n); } } } } public static void main(String[] args) { launch(args); } }