Java编写软件

来源:互联网 发布:无法连接主机 端口23 编辑:程序博客网 时间:2024/05/20 05:25

资源:UIControlsJavaFX.exe

1. 测试环境 JRE7U21 Win7
2. 如果JRE 6运行不成功则说明不支持JavaFX runtime
3. 双击UIControlsJavaFX.jar可以直接运行
4. 右键用rar软件打开UIControlsJavaFX.jar可以查看源码和JavaDoc

UIControlsJavaFX_V2.exe

版本2,实际上只改变了下闪屏界面的风格。

描述了JavaFX各个组件的应用,设计软件时可以参考或复制代码块以便加速软件开发过程。






解压,双击.jar文件即可运行。
测试环境: JRE 7U21, Win7 Ultimate


相关源码概览:(一些其他的附加资源如fonts, images, CSS等见上面开始的链接下载

package com.han;import java.io.File;import java.io.IOException;import java.util.Arrays;import java.util.List;import javax.imageio.ImageIO;import javafx.animation.KeyFrame;import javafx.animation.KeyValue;import javafx.animation.Timeline;import javafx.application.Application;import javafx.application.Platform;import javafx.beans.binding.DoubleBinding;import javafx.beans.property.ObjectProperty;import javafx.beans.property.SimpleBooleanProperty;import javafx.beans.property.SimpleDoubleProperty;import javafx.beans.property.SimpleObjectProperty;import javafx.beans.property.SimpleStringProperty;import javafx.beans.value.ChangeListener;import javafx.beans.value.ObservableValue;import javafx.collections.FXCollections;import javafx.collections.ObservableList;import javafx.concurrent.Worker;import javafx.embed.swing.SwingFXUtils;import javafx.event.ActionEvent;import javafx.event.Event;import javafx.event.EventHandler;import javafx.geometry.Bounds;import javafx.geometry.HPos;import javafx.geometry.Insets;import javafx.geometry.Orientation;import javafx.geometry.Point2D;import javafx.geometry.Pos;import javafx.geometry.Rectangle2D;import javafx.scene.Cursor;import javafx.scene.Node;import javafx.scene.Scene;import javafx.scene.control.Accordion;import javafx.scene.control.Button;import javafx.scene.control.CheckBox;import javafx.scene.control.CheckMenuItem;import javafx.scene.control.ChoiceBox;import javafx.scene.control.ColorPicker;import javafx.scene.control.ComboBox;import javafx.scene.control.ContentDisplay;import javafx.scene.control.ContextMenu;import javafx.scene.control.Control;import javafx.scene.control.Hyperlink;import javafx.scene.control.Label;import javafx.scene.control.ListCell;import javafx.scene.control.ListView;import javafx.scene.control.Menu;import javafx.scene.control.MenuBar;import javafx.scene.control.MenuItem;import javafx.scene.control.Pagination;import javafx.scene.control.PasswordField;import javafx.scene.control.ProgressBar;import javafx.scene.control.ProgressIndicator;import javafx.scene.control.RadioButton;import javafx.scene.control.RadioMenuItem;import javafx.scene.control.ScrollPane;import javafx.scene.control.Separator;import javafx.scene.control.SeparatorMenuItem;import javafx.scene.control.Slider;import javafx.scene.control.Tab;import javafx.scene.control.TabPane;import javafx.scene.control.TableCell;import javafx.scene.control.TableColumn;import javafx.scene.control.TableColumn.CellDataFeatures;import javafx.scene.control.TableColumn.SortType;import javafx.scene.control.TableRow;import javafx.scene.control.TableView;import javafx.scene.control.TextArea;import javafx.scene.control.TextField;import javafx.scene.control.TitledPane;import javafx.scene.control.Toggle;import javafx.scene.control.ToggleButton;import javafx.scene.control.ToggleGroup;import javafx.scene.control.ToolBar;import javafx.scene.control.Tooltip;import javafx.scene.control.TreeCell;import javafx.scene.control.TreeItem;import javafx.scene.control.TreeView;import javafx.scene.control.cell.TextFieldTableCell;import javafx.scene.control.cell.TextFieldTreeCell;import javafx.scene.effect.DropShadow;import javafx.scene.effect.Effect;import javafx.scene.effect.Glow;import javafx.scene.effect.Reflection;import javafx.scene.effect.SepiaTone;import javafx.scene.image.Image;import javafx.scene.image.ImageView;import javafx.scene.input.Clipboard;import javafx.scene.input.ClipboardContent;import javafx.scene.input.KeyCode;import javafx.scene.input.KeyCodeCombination;import javafx.scene.input.KeyCombination;import javafx.scene.input.KeyEvent;import javafx.scene.input.MouseButton;import javafx.scene.input.MouseEvent;import javafx.scene.layout.AnchorPane;import javafx.scene.layout.ColumnConstraints;import javafx.scene.layout.FlowPane;import javafx.scene.layout.GridPane;import javafx.scene.layout.HBox;import javafx.scene.layout.Pane;import javafx.scene.layout.Priority;import javafx.scene.layout.Region;import javafx.scene.layout.StackPane;import javafx.scene.layout.VBox;import javafx.scene.paint.Color;import javafx.scene.shape.Circle;import javafx.scene.shape.Rectangle;import javafx.scene.shape.SVGPath;import javafx.scene.text.Font;import javafx.scene.text.TextAlignment;import javafx.scene.web.HTMLEditor;import javafx.scene.web.WebEngine;import javafx.scene.web.WebView;import javafx.stage.FileChooser;import javafx.stage.Screen;import javafx.stage.Stage;import javafx.stage.StageStyle;import javafx.stage.Window;import javafx.util.Callback;import javafx.util.Duration;public class UIControlsJavaFX extends Application {public class Person {SimpleStringProperty firstName;SimpleStringProperty lastName;SimpleStringProperty email;Person(String firstName, String lastName, String email) {this.firstName = new SimpleStringProperty(firstName);this.lastName = new SimpleStringProperty(lastName);this.email = new SimpleStringProperty(email);}SimpleStringProperty firstNameProperty() {return firstName;}SimpleStringProperty lastNameProperty() {return lastName;}SimpleStringProperty emailProperty() {return email;}String getFirstName() {return firstName.get();}String getLastName() {return lastName.get();}String getEmail() {return email.get();}void setFirstName(String firstName) {this.firstName.set(firstName);}void setLastName(String lastName) {this.lastName.set(lastName);}void setEmail(String email) {this.email.set(email);}}/** * Member variable for storing initial position at the beginning of drag */private ObjectProperty<Point2D> anchor = new SimpleObjectProperty<Point2D>(null);/** * As this variable must be assigned by a value <b>in the inner class</b>, one should use  * the related object definition. */private SimpleDoubleProperty widthStage = new SimpleDoubleProperty();/** * As this variable must be assigned by a value <b>in the inner class</b>, one should use  * the related object definition. */private SimpleDoubleProperty heightStage = new SimpleDoubleProperty();/** * The initial focus owner when the stage is first shown */private RadioButton rbCalendar;private SimpleBooleanProperty maximized = new SimpleBooleanProperty(false);private SimpleObjectProperty<Rectangle2D> backupWindowBounds = new SimpleObjectProperty<Rectangle2D>(null);private Screen screen;private ScrollPane scrollPane;private Pane mainContainer;private int currentIndex = -1;public static void main(String[] args) {launch(args);}@Overridepublic void start(final Stage primaryStage) {primaryStage.getIcons().addAll(new Image(this.getClass().getResourceAsStream("graphics/WindowIcon16_16.jpg")),new Image(this.getClass().getResourceAsStream("graphics/WindowIcon32_32.jpg")), new Image(this.getClass().getResourceAsStream("graphics/WindowIcon64_64.jpg")));mainContainer = initStage(primaryStage);/* The font designed for Latin is not applicable for Chinese. However,  * The font designed for Chinese is applicable for Latin. Font must  * have the bold or italic version to have bold or italic effect. */System.out.println("Default system font: " + Font.getDefault());// Output the default system fontFont customFont = Font.loadFont(getClass().getResourceAsStream("fonts/华康少女字体.ttf"), 12);if (customFont != null) {System.out.println("Custom font loaded successfully: " + customFont);} else {System.out.println("Failure of loading custom font");}mainContainer.getChildren().addAll(createLabel(),createLabel2(), createLabel3(), createButton(),createButtonGraphic(),createRBGraphic(),createRadioButtonsApp(),createToggleButtonsApp(),createCheckBox(),createCheckBoxApp(),createChoiceBoxApp(),createPasswordFieldApp(),createNumericTextFieldApp(),createComboBoxApp(),createScrollPaneApp(),createListViewApp(),createTableViewApp(),createTreeViewApp(),createSeparatorApp(),createSliderApp(),createProgressApp(),createHyperlinkApp(),createTitledPaneAccordionApp(),createMenuBarApp(),createColorPickerApp(),createPaginationApp());primaryStage.show();// Show the primaryStage/* Set the initial focus owner when the stage is first shown (It is preferable to be placed  * after the stage is shown (because at that time all the nodes are realized)). */rbCalendar.requestFocus();}private Pane initStage(Stage primaryStage) {primaryStage.setTitle("Hello Java");primaryStage.initStyle(StageStyle.TRANSPARENT);//primaryStage.initStyle(StageStyle.DECORATED);/* The minWidth or minHeight is for the stage "DECORATED", it has on effect to the stage non "DECORATED". *///primaryStage.setMinWidth(600);//primaryStage.setMinHeight(400);VBox vBox = new VBox();vBox.setStyle("-fx-background-radius: 10px; -fx-spacing: 5px;");GridPane gridHeader = new GridPane();gridHeader.add(createCloseButton(), 0, 0);gridHeader.add(createMaximizeButton(primaryStage), 1, 0);gridHeader.add(createMinimizeButton(primaryStage), 2, 0);ColumnConstraints col1 = new ColumnConstraints();//col1.setPercentWidth(33);col1.setHgrow(Priority.ALWAYS);ColumnConstraints col2 = new ColumnConstraints();//col2.setPercentWidth(33);col2.setHgrow(Priority.ALWAYS);col2.setHalignment(HPos.CENTER);ColumnConstraints col3 = new ColumnConstraints();//col3.setPercentWidth(34);col3.setHgrow(Priority.ALWAYS);col3.setHalignment(HPos.RIGHT);gridHeader.getColumnConstraints().addAll(col1, col2, col3);final FlowPane mainContainer = new FlowPane();mainContainer.setStyle("-fx-background-color: white; " +"-fx-background-radius: 10px; " +"-fx-padding: 10px;" +"-fx-hgap: 30px; " +"-fx-vgap: 50px;");scrollPane = new ScrollPane();scrollPane.setStyle("-fx-background-radius: 10px;");scrollPane.setContent(mainContainer);//scrollPane.setPannable(true);//scrollPane.setVmin(0);//scrollPane.vmaxProperty().bind(new DoubleBinding() {////{//super.bind(mainContainer.heightProperty(), scrollPane.viewportBoundsProperty());//}////@Override//protected double computeValue() {//if (scrollPane.getViewportBounds() != null) {//return mainContainer.getHeight() - scrollPane.getViewportBounds().getHeight();//} else {//return 0;//}//}////});/* The prefWidthProperty() and prefWrapLengthProperty() in FlowPane is not the same thing.  * prefWrapLengthProperty() is for "content" not for the whole width which could contain the "padding".  * You can also use "scrollPane.setFitToWidth(true);" to realize the same effect. */mainContainer.prefWidthProperty().bind(new DoubleBinding() {{super.bind(scrollPane.viewportBoundsProperty());}@Overrideprotected double computeValue() {Bounds bounds = scrollPane.getViewportBounds();if (bounds == null) {return 0;} else {return bounds.getWidth();}}});vBox.getChildren().addAll(gridHeader, scrollPane);VBox.setVgrow(scrollPane, Priority.ALWAYS);AnchorPane root = new AnchorPane();root.setStyle("-fx-border-color: black; " +"-fx-border-width: 1px; " +"-fx-border-radius: 10px; " +"-fx-background-color: rgba(0, 0, 0, 0); " +"-fx-background-radius: 10px;");DropShadow dropShadow = new DropShadow();dropShadow.setRadius(20.0);// dropShadow.setSpread(0.2);root.setEffect(dropShadow);enableDragging(root);root.getChildren().add(vBox);AnchorPane.setTopAnchor(vBox, 0.0);AnchorPane.setRightAnchor(vBox, 10.0);AnchorPane.setBottomAnchor(vBox, 10.0);AnchorPane.setLeftAnchor(vBox, 10.0);AnchorPane superRoot = new AnchorPane();superRoot.getChildren().add(root);AnchorPane.setTopAnchor(root, 10.0);AnchorPane.setRightAnchor(root, 10.0);AnchorPane.setBottomAnchor(root, 10.0);AnchorPane.setLeftAnchor(root, 10.0);Scene scene = new Scene(superRoot, 900, 650, Color.TRANSPARENT);scene.getStylesheets().add(getClass().getResource("controls.css").toExternalForm());primaryStage.setScene(scene);return mainContainer;}/** * Define a "Close" button, which is indispensable for an undecorated stage *  * @return a "Close" button */private Node createCloseButton() {Button closeButton = new Button("Close");closeButton.setId("button-close");closeButton.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent event) {Platform.exit();}});return closeButton;}/** * Define a "Maximize" button *  * @return a "Maximize" button */private Node createMaximizeButton(final Stage primaryStage) {Button maximizeButton = new Button("Maximize");maximizeButton.setId("button-maximize");maximizeButton.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent event) {/* Toggle the maximizing action */ObservableList<Screen> screens = Screen.getScreensForRectangle(primaryStage.getX(), primaryStage.getY(), 1, 1);if (screens.isEmpty()) {screen = Screen.getScreensForRectangle(0, 0, 1, 1).get(0);} else {screen = screens.get(0);}        if (maximized.get()) {            maximized.set(false);            if (backupWindowBounds != null) {            primaryStage.setX(backupWindowBounds.get().getMinX());            primaryStage.setY(backupWindowBounds.get().getMinY());            primaryStage.setWidth(backupWindowBounds.get().getWidth());            primaryStage.setHeight(backupWindowBounds.get().getHeight());            }        } else {        maximized.set(true);            backupWindowBounds.set(new Rectangle2D(primaryStage.getX(), primaryStage.getY(), primaryStage.getWidth(), primaryStage.getHeight()));            primaryStage.setX(screen.getVisualBounds().getMinX());            primaryStage.setY(screen.getVisualBounds().getMinY());            primaryStage.setWidth(screen.getVisualBounds().getWidth());            primaryStage.setHeight(screen.getVisualBounds().getHeight());        }}});return maximizeButton;}/** * Define a "Minimize" button *  * @return a "Minimize" button */private Node createMinimizeButton(final Stage primaryStage) {Button minimizeButton = new Button("Minimize");minimizeButton.setId("button-minimize");minimizeButton.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent event) {primaryStage.setIconified(true);}});return minimizeButton;}/** * Enable the root node to be dragged. Realize some drag functions. *  * @param root - the root node */private void enableDragging(final AnchorPane root) {/* This mouse event is for resizing window. Define some specific cursor patterns. */root.setOnMouseMoved(new EventHandler<MouseEvent>() {public void handle(MouseEvent me) {if ((me.getX() > root.getWidth() - 10 && me.getX() < root.getWidth() + 10)&& (me.getY() > root.getHeight() - 10 && me.getY() < root.getHeight() + 10)) {root.setCursor(Cursor.SE_RESIZE);} else if (me.getX() > root.getWidth() - 5 && me.getX() < root.getWidth() + 5) {root.setCursor(Cursor.H_RESIZE);} else if (me.getY() > root.getHeight() - 5 && me.getY() < root.getHeight() + 5) {root.setCursor(Cursor.V_RESIZE);} else {root.setCursor(Cursor.DEFAULT);}}});/* when mouse button is pressed, save the initial position of screen. */root.setOnMousePressed(new EventHandler<MouseEvent>() {public void handle(MouseEvent me) {Window primaryStage = root.getScene().getWindow();anchor.set(new Point2D(me.getScreenX() - primaryStage.getX(), me.getScreenY() - primaryStage.getY()));widthStage.set(primaryStage.getWidth());heightStage.set(primaryStage.getHeight());}});/* when mouse button is released, clear the initial position of screen. This action is very important,  * because it can be a judge to avoid mouse interaction with other nodes as ChoiceBox. */root.setOnMouseReleased(new EventHandler<MouseEvent>() {public void handle(MouseEvent me) {anchor.set(null);}});/* when screen is dragged, translate it accordingly. Note that the transparent pixels part contained in  * the root will not react to the drag. But translucent color is able to. */root.setOnMouseDragged(new EventHandler<MouseEvent>() {public void handle(MouseEvent me) {if (anchor.get() != null) {// The drag event on the root really takes place.Window primaryStage = root.getScene().getWindow();double stageMinWidth = 600;double stageMinHeight = 400;if (root.getCursor() == Cursor.H_RESIZE) {primaryStage.setWidth(Math.max(stageMinWidth, widthStage.get() + (me.getScreenX() - (anchor.get().getX() + primaryStage.getX()))));} else if (root.getCursor() == Cursor.V_RESIZE) {primaryStage.setHeight(Math.max(stageMinHeight, heightStage.get() + (me.getScreenY() - (anchor.get().getY() + primaryStage.getY()))));} else if (root.getCursor() == Cursor.SE_RESIZE) {primaryStage.setWidth(Math.max(stageMinWidth, widthStage.get() + (me.getScreenX() - (anchor.get().getX() + primaryStage.getX()))));primaryStage.setHeight(Math.max(stageMinHeight, heightStage.get() + (me.getScreenY() - (anchor.get().getY() + primaryStage.getY()))));} else {// moving the stageif (maximized.get()) {                        anchor.set(new Point2D(((me.getScreenX() - primaryStage.getX()) / primaryStage.getWidth()) * backupWindowBounds.get().getWidth(),             me.getScreenY() - screen.getVisualBounds().getMinY()));                        primaryStage.setWidth(backupWindowBounds.get().getWidth());            primaryStage.setHeight(backupWindowBounds.get().getHeight());                        maximized.set(false);}primaryStage.setX(me.getScreenX() - anchor.get().getX());primaryStage.setY(me.getScreenY() - anchor.get().getY());}}}});}/** * Define a label * @return a label */private Node createLabel() {Label label = new Label();label.setText("Search");label.setFont(new Font("Arial", 30));label.setGraphic(new ImageView(new Image(getClass().getResourceAsStream("graphics/labels.jpg"))));label.setTextFill(Color.web("#0076a3"));label.setGraphicTextGap(label.getGraphicTextGap());return label;}/** * Define another label. * @return a label */private Node createLabel2() {Label label2 = new Label();label2.setText("Values");label2.setRotate(270);label2.setTranslateY(0);label2.setFont(new Font("Cambria", 32));return label2;}/** * Define a third label * @return a label */private Node createLabel3() {final Label label3 = new Label();label3.setText("A label that needs hovered and is wrappable");label3.setWrapText(true);label3.setPrefWidth(200);label3.setOnMouseEntered(new EventHandler<MouseEvent>() {@Overridepublic void handle(MouseEvent event) {label3.setScaleX(1.5);label3.setScaleY(1.5);}});label3.setOnMouseExited(new EventHandler<MouseEvent>() {@Overridepublic void handle(MouseEvent event) {label3.setScaleX(1.0);label3.setScaleY(1.0);}});return label3;}/** * Define a button * @return a button */private Node createButton() {Button button = new Button();button.setEffect(new Reflection());button.setText("Say 'Hello Java'");button.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent event) {System.out.println("Hello Java!");}});/* add an animation effect */Timeline timeline = new Timeline();timeline.setCycleCount(Timeline.INDEFINITE);timeline.setAutoReverse(true);timeline.getKeyFrames().addAll(new KeyFrame(Duration.ZERO, new KeyValue(button.opacityProperty(), 1.0)),new KeyFrame(Duration.seconds(5), new KeyValue(button.opacityProperty(), 0.0)));timeline.play();/* set CSS style */button.setStyle("-fx-font: 14px 'Cambria'; " +"-fx-text-fill: #006464; " +"-fx-background-color: #e79423; " +"-fx-background-radius: 20.0; " +"-fx-padding: 5.0;");return button;}/** * Define a button with icon * @return a button */private Node createButtonGraphic() {final Button buttonGraphic = new Button("Accept", new ImageView(new Image(getClass().getResourceAsStream("graphics/ok.png"))));buttonGraphic.setFont(Font.font("Arial", 22));/* set button actions */buttonGraphic.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent event) {buttonGraphic.setText("Accepted");buttonGraphic.setFont(new Font(buttonGraphic.getFont().getName(), 16));}});buttonGraphic.setOnMouseEntered(new EventHandler<MouseEvent>() {@Overridepublic void handle(MouseEvent event) {buttonGraphic.setEffect(new DropShadow());}});buttonGraphic.setOnMouseExited(new EventHandler<MouseEvent>() {@Overridepublic void handle(MouseEvent event) {buttonGraphic.setEffect(null);}});/* set CSS style */buttonGraphic.setStyle("-fx-base: #b6e7c9;");return buttonGraphic;}/** * Creating a Graphical Radio Button * @return a radio button */private Node createRBGraphic() {RadioButton rbGraphic = new RadioButton("Decline");rbGraphic.setGraphic(new ImageView(new Image(getClass().getResourceAsStream("graphics/not.png"))));rbGraphic.setStyle("-fx-padding: 0 10 0 10;");return rbGraphic;}/** * Creating a radio buttons app which uses a toggle group. * @return a horizontal box */private Node createRadioButtonsApp() {VBox vBoxForRBs = new VBox();final ToggleGroup toggleGroup = new ToggleGroup();RadioButton rbHome = new RadioButton("Home");rbHome.setToggleGroup(toggleGroup);rbCalendar = new RadioButton("Calendar");rbCalendar.setSelected(true);rbCalendar.setToggleGroup(toggleGroup);RadioButton rbContacts = new RadioButton("Contacts");rbContacts.setToggleGroup(toggleGroup);vBoxForRBs.getChildren().add(rbHome);vBoxForRBs.getChildren().add(rbCalendar);vBoxForRBs.getChildren().add(rbContacts);vBoxForRBs.setSpacing(10);Image imageHome = new Image(getClass().getResourceAsStream("graphics/Home.jpg"));Image imageCalendar = new Image(getClass().getResourceAsStream("graphics/Calendar.jpg"));Image imageContacts = new Image(getClass().getResourceAsStream("graphics/Contacts.jpg"));rbHome.setUserData(imageHome);rbCalendar.setUserData(imageCalendar);rbContacts.setUserData(imageContacts);final ImageView icon = new ImageView(imageCalendar);HBox hBoxForRBsAndIcon = new HBox();hBoxForRBsAndIcon.getChildren().addAll(vBoxForRBs, icon);hBoxForRBsAndIcon.setSpacing(20);hBoxForRBsAndIcon.setPadding(new Insets(20, 10, 10, 20));toggleGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {@Overridepublic void changed(ObservableValue<? extends Toggle> ov, Toggle old_toggle, Toggle new_toggle) {if (new_toggle != null) {icon.setImage((Image) new_toggle.getUserData());}}});return hBoxForRBsAndIcon;}/** * Creating a toggle buttons app which uses a toggle group * @return a vertical box */private VBox createToggleButtonsApp() {ToggleButton tb1 = new ToggleButton("Minor");ToggleButton tb2 = new ToggleButton("Major");ToggleButton tb3 = new ToggleButton("Critical");/* A method to directly obtain the preferred width of node */// final Scene snapScene = new Scene(tb1);// snapScene.snapshot(null);// System.out.println(tb1.getWidth());final Rectangle rect = new Rectangle();rect.setFill(Color.WHITE);rect.widthProperty().bind(tb1.widthProperty().add(tb2.widthProperty()).add(tb3.widthProperty()));rect.setHeight(50);rect.setArcHeight(10);rect.setArcWidth(10);rect.setStroke(Color.DARKGRAY);rect.setStrokeWidth(2);Label labelPriority = new Label("Priority:");HBox hBoxForTBs = new HBox();hBoxForTBs.getChildren().addAll(tb1, tb2, tb3);VBox vBox = new VBox();vBox.getChildren().addAll(labelPriority, hBoxForTBs, rect);/* realize the corresponding logical function */final ToggleGroup toggleGroup = new ToggleGroup();tb1.setToggleGroup(toggleGroup);tb2.setToggleGroup(toggleGroup);tb3.setToggleGroup(toggleGroup);tb1.setUserData(Color.LIGHTGREEN);tb2.setUserData(Color.LIGHTBLUE);tb3.setUserData(Color.SALMON);toggleGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {public void changed(ObservableValue<? extends Toggle> ov, Toggle old_toggle, Toggle new_toggle) {if (new_toggle == null) {rect.setFill(Color.WHITE);} else {rect.setFill((Color) new_toggle.getUserData());}}});/* set CSS style */tb1.setStyle("-fx-base: lightgreen;");tb2.setStyle("-fx-base: lightblue;");tb3.setStyle("-fx-base: salmon;");return vBox;}/** * Define a check box allowing the cycle state to contain three states * @return a check box */private Node createCheckBox() {CheckBox checkBox = new CheckBox("Allow indeterminate");checkBox.setIndeterminate(true);// set the state indeterminate when initializationcheckBox.setAllowIndeterminate(true);// allow the cycle state containing the indeterminate state, the value false by defaultreturn checkBox;}/** * Creating a checkBox related app * @return a horizontal box */private HBox createCheckBoxApp() {HBox hBox = new HBox();VBox vBox = new VBox();final HBox hBoxForIcons = new HBox();final String[] names = { "Security", "Project", "Chart" };CheckBox[] checkBoxs = new CheckBox[names.length];final ImageView[] imageViews = new ImageView[names.length];for (int i = 0; i < names.length; i++) {final String name = names[i];CheckBox checkBox = checkBoxs[i] = new CheckBox();checkBox.setId("check-box-custom");checkBox.setText(name);final ImageView imageView = imageViews[i] = new ImageView(new Image(getClass().getResourceAsStream("graphics/" + name + ".png")));imageView.setUserData(i);checkBox.selectedProperty().addListener(new ChangeListener<Boolean>() {@Overridepublic void changed(ObservableValue<? extends Boolean> ov, Boolean old_boolean, Boolean new_boolean) {if (new_boolean) {/* add the imageView to the observable list in order. */if (!hBoxForIcons.getChildren().isEmpty()) {Object[] imageViewsTemp = hBoxForIcons.getChildren().toArray();int k;for (k = 0; k < imageViewsTemp.length; k++) {if ((int) imageView.getUserData() < (int) ((ImageView) imageViewsTemp[k]).getUserData()) {hBoxForIcons.getChildren().add(k, imageView);break;}}if (k == imageViewsTemp.length) {hBoxForIcons.getChildren().add(k, imageView);}} else {hBoxForIcons.getChildren().add(imageView);}} else {hBoxForIcons.getChildren().remove(imageView);}}});vBox.getChildren().add(checkBox);/* set CSS style for check box */checkBox.setStyle("-fx-border-color: lightblue; " +"-fx-border-style: dotted; " +"-fx-border-radius: 5; " +"-fx-border-width: 2; " +"-fx-border-insets: -5;");}Rectangle rect = new Rectangle(90, 30);rect.setArcHeight(10);rect.setArcWidth(10);rect.setFill(Color.rgb(41, 41, 41));StackPane stackPane = new StackPane();stackPane.getChildren().addAll(rect, hBoxForIcons);StackPane.setAlignment(rect, Pos.TOP_CENTER);hBox.getChildren().addAll(vBox, stackPane);/* set CSS style */// stackPane.setStyle("-fx-background-color: green;");// for debugginghBoxForIcons.setStyle("-fx-padding: 0 5 0 5;");hBox.setStyle("-fx-spacing: 20; -fx-padding: 10;");vBox.setStyle("-fx-spacing: 15;");return hBox;}/** * Creating a choice box app * @return a horizontal box */private Node createChoiceBoxApp() {ChoiceBox<Object> choiceBox = new ChoiceBox<Object>(FXCollections.observableArrayList("English", "Español", "Русский", new Separator(), "简体中文", "日本語"));choiceBox.setValue("简体中文");// set the first value to display when startingTooltip toolTip = new Tooltip("Select the language");// set the tool tip for the choice boxtoolTip.setId("tooltip-custom");choiceBox.setTooltip(toolTip);/* for the "new Separator()" node, we use an empty string for placeholder */final String[] display = new String[] { "Hello", "Hola", "Привет", "", "你好", "こんにちは" };/* we can use setText() later for dynamically programming */final Label label = new Label(display[choiceBox.getItems().indexOf(choiceBox.getValue())]);label.setFont(Font.font("UniSun", 12));/* lay out all the controls */HBox hBox = new HBox();hBox.getChildren().addAll(choiceBox, label);hBox.setSpacing(10);hBox.setAlignment(Pos.TOP_LEFT);hBox.setPadding(new Insets(0, 5, 0, 5));/* set the behavior for the choice box */choiceBox.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {@Overridepublic void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {label.setText(display[(Integer) newValue]);}});return hBox;}/** * Creating a combo box app * @return a grid pane */private Node createComboBoxApp() {final ComboBox<String> emailComboBox = new ComboBox<String>();emailComboBox.getItems().addAll("jacob.smith@example.com", "isabella.johnson@example.com", "ethan.williams@example.com", "emma.jones@example.com","michael.brown@example.com");emailComboBox.setVisibleRowCount(4);emailComboBox.setPrefWidth(250);emailComboBox.setMaxWidth(Double.MAX_VALUE);emailComboBox.setPromptText("Email address");emailComboBox.setEditable(true);/* regex = regular expression */final String regex = "\\w{1,}@\\w{1,}\\.\\w{1,}";final String regex2 = "\\w{1,}\\.\\w{1,}@\\w{1,}\\.\\w{1,}";ComboBox<String> priorityComboBox = new ComboBox<String>(FXCollections.observableArrayList("Highest", "High", "Normal", "Low", "Lowest"));priorityComboBox.setValue("Normal");final GridPane gridPane = new GridPane();gridPane.setStyle("-fx-vgap: 4; -fx-hgap: 10; -fx-padding: 5;");//gridPane.setGridLinesVisible(true);ColumnConstraints col1 = new ColumnConstraints();ColumnConstraints col2 = new ColumnConstraints();col2.setHgrow(Priority.ALWAYS);col2.setFillWidth(true);ColumnConstraints col3 = new ColumnConstraints(100);// This is a convenient method for setting the preferred width to the fixed value and the minWidth and maxWidth to the CONSTRAIN_TO_PREF flag to ensure the column is always at that width.col3.setHalignment(HPos.RIGHT);ColumnConstraints col4 = new ColumnConstraints(100);col4.setHalignment(HPos.RIGHT);gridPane.getColumnConstraints().addAll(col1, col2, col3, col4);gridPane.add(new Label("To:"), 0, 0);gridPane.add(emailComboBox, 1, 0);Label priorityLabel = new Label("Priority:");gridPane.add(priorityLabel, 2, 0);gridPane.add(priorityComboBox, 3, 0);gridPane.add(new Label("Subject:"), 0, 1);final TextField subject = new TextField();subject.setPromptText("input a subject...");gridPane.add(subject, 1, 1, 3, 1);final TextArea content = new TextArea();content.setPrefHeight(200);content.setPromptText("input the content of message here...");gridPane.add(content, 0, 2, 4, 1);Button button = new Button("Send");gridPane.add(button, 0, 3);final Label label = new Label();label.prefWidthProperty().bind(emailComboBox.widthProperty().add(gridPane.getHgap()).add(col3.prefWidthProperty()));label.setWrapText(true);// when there is ellipsis, it will be replaced by wrapped text. Normally this will happen when the length of content text exceeds its label's preferred length.gridPane.add(label, 1, 3, 2, 1);final Hyperlink toHTMLEditor = new Hyperlink("advanced mode");gridPane.add(toHTMLEditor, 3, 3);final Hyperlink backToTextArea = new Hyperlink("simple mode");final HTMLEditor htmlEditor = new HTMLEditor();final TabPane tabPane = new TabPane();tabPane.setPrefHeight(200);final Tab tab1 = new Tab("Advanced mode");tab1.setClosable(false);final Tab tab2 = new Tab("HTML code");tab2.setClosable(false);tabPane.getTabs().addAll(tab1, tab2);tab1.setContent(htmlEditor);final TextArea htmlCode = new TextArea();htmlCode.setWrapText(true);tab2.setContent(htmlCode);/* set the actions */toHTMLEditor.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent arg0) {gridPane.getChildren().remove(content);gridPane.getChildren().remove(toHTMLEditor);gridPane.add(tabPane, 0, 2, 4, 1);gridPane.add(backToTextArea, 3, 3);}});backToTextArea.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent arg0) {gridPane.getChildren().remove(tabPane);gridPane.getChildren().remove(backToTextArea);gridPane.add(content, 0, 2, 4, 1);gridPane.add(toHTMLEditor, 3, 3);}});tab1.setOnSelectionChanged(new EventHandler<Event>() {@Overridepublic void handle(Event arg0) {if (tab1.isSelected()) {if (!gridPane.getChildren().contains(backToTextArea)) {gridPane.add(backToTextArea, 3, 3);}htmlEditor.setHtmlText(htmlCode.getText());}}});tab2.setOnSelectionChanged(new EventHandler<Event>() {@Overridepublic void handle(Event arg0) {if (tab2.isSelected()) {gridPane.getChildren().remove(backToTextArea);htmlCode.setText(htmlEditor.getHtmlText());}}});button.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent actionEvent) {String emailAddress = emailComboBox.getValue();if (emailAddress == null) {label.setText("You haven't click the email address box!");} else if (emailAddress.isEmpty()) {label.setText("Your email address specified is an empty string!");} else {if (emailAddress.matches(regex) || emailAddress.matches(regex2)) {label.setText("Your message was sent to " + emailAddress);emailComboBox.setValue(null);subject.clear();content.clear();} else {label.setText("Your input email address is not a valid email address!");}}}});/* Implement a cell factory mechanism for the priority combo box */priorityComboBox.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {@Overridepublic ListCell<String> call(ListView<String> param) {return new ListCell<String>() {{setPrefWidth(70);}@Overrideprotected void updateItem(String item, boolean empty) {super.updateItem(item, empty);// is necessaryif (item == null || empty) {setText(null);} else {setText(item);if (item.contains("High")) {setTextFill(Color.RED);} else if (item.contains("Low")) {setTextFill(Color.GREEN);} else {setTextFill(Color.BLACK);}}}};}});return gridPane;}/** * Creating a password field * @return a vertical box */private Node createPasswordFieldApp() {VBox vBox = new VBox();HBox hBox = new HBox();final PasswordField pf = new PasswordField();hBox.getChildren().addAll(new Label("Password"), pf);final Label label1 = new Label();vBox.getChildren().addAll(hBox, label1);/* set actions */pf.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent event) {if (pf.getText().equals("T2f$Ay!")) {label1.setText("Your password has been confirmed");label1.setTextFill(Color.rgb(21, 117, 84));} else {label1.setText("Your password is incorrect!");label1.setTextFill(Color.rgb(210, 39, 30));}pf.clear();}});/* set CSS styles */hBox.setStyle("-fx-spacing: 10px; -fx-alignment: top-left;");vBox.setStyle("-fx-spacing: 10px; -fx-alignment: center;");return vBox;}/** * Creating a numeric text field * @return a vertical box */private Node createNumericTextFieldApp() {VBox vBox = new VBox();HBox hBox = new HBox();Label label2 = new Label("$");final Label indication = new Label();TextField numericTextField = new TextField() {@Overridepublic void replaceText(int start, int end, String text) {if (!text.matches("[a-z, A-Z]")) {super.replaceText(start, end, text);indication.setText(null);} else {indication.setText("Enter a numeric value");}}};hBox.getChildren().addAll(label2, numericTextField);vBox.getChildren().addAll(hBox, indication);// set CSS stylehBox.setStyle("-fx-spacing: 10px; -fx-alignment: top-left;");vBox.setStyle("-fx-spacing: 10px; -fx-alignment: center;");return vBox;}/** * Creating a scroll pane app * @return a vertical box */private Node createScrollPaneApp() {final VBox vb1 = new VBox();vb1.setSpacing(10);vb1.setPadding(new Insets(5));VBox vb2 = new VBox();final String[] imageNames = new String[] { "fw1.jpg", "fw2.jpg", "fw3.jpg", "fw4.jpg" };DropShadow shadow = new DropShadow();shadow.setColor(Color.GRAY);shadow.setOffsetX(2);shadow.setOffsetY(2);for (int i = 0; i < imageNames.length; i++) {ImageView imageView = new ImageView(new Image(getClass().getResourceAsStream("graphics/" + imageNames[i])));imageView.setEffect(shadow);vb1.getChildren().add(imageView);}final ScrollPane scrollPane = new ScrollPane();scrollPane.setPrefHeight(140);scrollPane.setPrefWidth(150);scrollPane.setStyle("-fx-background-color: black;");//scrollPane.prefViewportWidthProperty().bind(vb1.widthProperty());scrollPane.setVmin(0.0);scrollPane.setVmax(3.5);scrollPane.setContent(vb1);final Label imageName = new Label();vb2.getChildren().addAll(scrollPane, imageName);scrollPane.vvalueProperty().addListener(new ChangeListener<Number>() {@Overridepublic void changed(ObservableValue<? extends Number> ov, Number oldVvalue, Number newVvalue) {imageName.setText(imageNames[(int) Math.floor(newVvalue.doubleValue())]);}});return vb2;}/** * Creating a list view app * @return a vertical box */private Node createListViewApp() {final ListView<String> lv = new ListView<String>();final ObservableList<String> colors = FXCollections.observableArrayList("chocolate", "salmon", "gold", "coral", "darkorchid", "darkgoldenrod", "lightsalmon", "black", "rosybrown", "blue", "blueviolet", "brown");lv.setItems(colors);lv.setPrefSize(200, 200);final Callback<ListView<String>, ListCell<String>> lvCallback = new Callback<ListView<String>, ListCell<String>>() {@Overridepublic ListCell<String> call(ListView<String> arg0) {return new ListCell<String>() {@Overridepublic void updateItem(String item, boolean empty) {super.updateItem(item, empty);if (item != null) {Rectangle rect = new Rectangle(100, 20);rect.setFill(Color.web(item));setGraphic(rect);}}};}};lv.setCellFactory(lvCallback);VBox vBox = new VBox();final Label label = new Label();label.setFont(Font.font("Verdana", 20));final ComboBox<String> cb = new ComboBox<String>(colors);final int cbIndex = 1;// the index for combo box that we want to placelv.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {@Overridepublic void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {int newIndex = newValue.intValue();if (newIndex == cbIndex) {// is selectedlv.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {@Overridepublic ListCell<String> call(ListView<String> p) {return new ListCell<String>() {@Overridepublic void updateItem(String item, boolean empty) {super.updateItem(item, empty);if (item != null) {if (getIndex() == cbIndex) {setGraphic(cb);cb.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {@Overridepublic ListCell<String> call(ListView<String> p) {return new ListCell<String>() {private final Rectangle rectangle;{setContentDisplay(ContentDisplay.GRAPHIC_ONLY);rectangle = new Rectangle(100, 20);}@Overrideprotected void updateItem(String item, boolean empty) {super.updateItem(item, empty);if (item == null || empty) {setGraphic(null);} else {rectangle.setFill(Color.web(item));setGraphic(rectangle);}}};}});cb.setButtonCell(new ListCell<String>() {private final Rectangle rectangle;{setContentDisplay(ContentDisplay.GRAPHIC_ONLY);rectangle = new Rectangle(100, 20);}@Overrideprotected void updateItem(String item, boolean empty) {super.updateItem(item, empty);if (item == null || empty) {setGraphic(null);} else {rectangle.setFill(Color.web(item));setGraphic(rectangle);}}});cb.setValue(lv.getItems().get(cbIndex));} else {Rectangle rect = new Rectangle(100, 20);rect.setFill(Color.web(item));setGraphic(rect);}}}};}});} else if (oldValue != null) {int oldIndex = oldValue.intValue();if (oldIndex == cbIndex) {// is deselectedlv.getItems().set(cbIndex, cb.getValue());// update the list view datalv.setCellFactory(lvCallback);}}String color = lv.getItems().get(newIndex);// set the value of the labellabel.setText(color);label.setTextFill(Color.web(color));}});Label note = new Label("The second cell is a combo box.");vBox.getChildren().addAll(lv, label, note);return vBox;}/** * Creating a table view app * @return a vertical box */@SuppressWarnings("unchecked")private Node createTableViewApp() {Label label = new Label("Address Book");label.setFont(new Font("Arial", 20));final TableView<Person> table = new TableView<Person>();table.setId("table-view-custom");final ObservableList<Person> data = FXCollections.observableArrayList(new Person("Jacob", "Smith", "jacob.smith@example.com"), new Person("Isabella", "Johnson", "isabella.johnson@example.com"), new Person("Ethan", "Williams", "ethan.williams@example.com"), new Person("Emma", "Jones", "emma.jones@example.com"), new Person("Michael", "Brown", "michael.brown@example.com"));TableColumn<Person, String> firstNameCol = new TableColumn<Person, String>("First Name");TableColumn<Person, String> lastNameCol = new TableColumn<Person, String>("Last Name");TableColumn<Person, String> emailCol = new TableColumn<Person, String>("Email");firstNameCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Person, String>, ObservableValue<String>>() {@Overridepublic ObservableValue<String> call(CellDataFeatures<Person, String> cellDataFeatures) {return cellDataFeatures.getValue().firstNameProperty();}});lastNameCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Person, String>, ObservableValue<String>>() {@Overridepublic ObservableValue<String> call(CellDataFeatures<Person, String> cellDataFeatures) {return cellDataFeatures.getValue().lastNameProperty();}});emailCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Person, String>, ObservableValue<String>>() {@Overridepublic ObservableValue<String> call(CellDataFeatures<Person, String> cellDataFeatures) {return cellDataFeatures.getValue().emailProperty();}});table.setItems(data);table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);table.setPrefHeight(200);/* Set sort (must after the initialization of table) */table.getSortOrder().addAll(firstNameCol, lastNameCol, emailCol);firstNameCol.setSortType(SortType.ASCENDING);lastNameCol.setSortType(SortType.DESCENDING);emailCol.setSortType(SortType.ASCENDING);/* Implementing cell editing */table.setEditable(true);Callback<TableColumn<Person, String>, TableCell<Person, String>> cellFactory = TextFieldTableCell.forTableColumn();firstNameCol.setCellFactory(cellFactory);lastNameCol.setCellFactory(cellFactory);emailCol.setCellFactory(cellFactory);/* However, the edit commit event is fired by enter key, which is determined by the implementation  * of the TextField class. But we users normally want to commit while the cell loses its focus. So we  * have to reimplement the cell factory rather than using TextFieldTableCell. */Callback<TableColumn<Person, String>, TableCell<Person, String>> cellFactoryNew = new Callback<TableColumn<Person, String>, TableCell<Person, String>> () {@Overridepublic TableCell<Person, String> call(TableColumn<Person, String> param) {TableCell<Person, String> cell = new TableCell<Person, String>() {TableRow<Person> row;final MenuItem delete = new MenuItem("Delete");final ContextMenu contextMenu = new ContextMenu(delete);{delete.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent e) {data.remove(row.getItem());}});}/** * When double-clicks, enter the editing state. At this moment, creating a text field for editing.  * @see javafx.scene.control.TableCell#startEdit() */@Overridepublic void startEdit() {super.startEdit();final TextField textField = new TextField(getItem());/* Realize the focus losing for committing */textField.focusedProperty().addListener(new ChangeListener<Boolean>() {@Overridepublic void changed(ObservableValue<? extends Boolean> ov, Boolean oldValue, Boolean newValue) {if (!newValue) {// the text field loses focuscommitEdit(textField.getText());// transit from an editing state into a non-editing state}}});/* Realize the key enter for committing, we can also use setOnAction */textField.setOnKeyPressed(new EventHandler<KeyEvent>() {@Overridepublic void handle(KeyEvent event) {if (event.getCode() == KeyCode.ENTER) {commitEdit(textField.getText());}}});setText(null);setGraphic(textField);}/** * When a Esc key pressed, this method is fired. * @see javafx.scene.control.TableCell#cancelEdit() */@Overridepublic void cancelEdit() {super.cancelEdit();/* Realize the relevant actions */setText(getItem());setGraphic(null);}@Overridepublic void updateItem(String item, boolean empty) {super.updateItem(item, empty);/* add a context menu */row = getTableRow();if (row != null) {if (row.getItem() != null) {row.setContextMenu(contextMenu);}}setText(getItem());setGraphic(null);}};return cell;}};firstNameCol.setCellFactory(cellFactoryNew);lastNameCol.setCellFactory(cellFactoryNew);emailCol.setCellFactory(cellFactoryNew);final TextField firstName = new TextField();final TextField lastName = new TextField();final TextField email = new TextField();firstName.setPromptText("First Name");lastName.setPromptText("Last Name");email.setPromptText("Email");firstName.prefWidthProperty().bind(firstNameCol.prefWidthProperty());lastName.prefWidthProperty().bind(lastNameCol.prefWidthProperty());email.prefWidthProperty().bind(emailCol.prefWidthProperty());Button addButton = new Button("Add");addButton.setId("button-custom");addButton.prefHeightProperty().bind(addButton.widthProperty());Circle circle = new Circle();circle.centerXProperty().bind(addButton.widthProperty().divide(2));circle.centerYProperty().bind(addButton.heightProperty().divide(2));circle.radiusProperty().bind(addButton.widthProperty().divide(2));addButton.setClip(circle);addButton.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent arg0) {data.add(new Person(firstName.getText(), lastName.getText(), email.getText()));firstName.clear();lastName.clear();email.clear();}});HBox hBox = new HBox();hBox.getChildren().addAll(firstName, lastName, email, addButton);VBox vBox = new VBox();vBox.getChildren().addAll(label, table, hBox);return vBox;}private Node createTreeViewApp() {TreeItem<String> rootItem = new TreeItem<String>("MyCompany Human Resources", new ImageView(new Image(getClass().getResourceAsStream("graphics/root.png"))));rootItem.setExpanded(true);TreeView<String> treeView = new TreeView<String>(rootItem);/* define data model */List<Employee> employees = Arrays.asList(new Employee("Ethan Williams", "Sales Department"),new Employee("Emma Jones", "Sales Department"),            new Employee("Michael Brown", "Sales Department"),            new Employee("Anna Black", "Sales Department"),            new Employee("Rodger York", "Sales Department"),            new Employee("Susan Collins", "Sales Department"),            new Employee("Mike Graham", "IT Support"),            new Employee("Judy Mayer", "IT Support"),            new Employee("Gregory Smith", "IT Support"),            new Employee("Jacob Smith", "Accounts Department"),            new Employee("Isabella Johnson", "Accounts Department"));/* Add the employees data to tree (So use the foreach loop) */for (Employee employee : employees) {TreeItem<String> nameItem = new TreeItem<String>(employee.getName());boolean found = false;for (TreeItem<String> treeItem : rootItem.getChildren()) {if (treeItem.getValue().equals(employee.getDepartment())) {treeItem.getChildren().add(nameItem);found = true;break;}}if (!found) {TreeItem<String> deptItem = new TreeItem<String>(employee.getDepartment(), new ImageView(new Image(getClass().getResourceAsStream("graphics/department.png"))));rootItem.getChildren().add(deptItem);deptItem.getChildren().add(nameItem);}}/* make tree items editable */treeView.setEditable(true);treeView.setCellFactory(TextFieldTreeCell.forTreeView());// the simplest default way, but will override the cell (label) graphic to be null.treeView.setCellFactory(new Callback<TreeView<String>, TreeCell<String>>(){// So we customize an implementation of text field editing.            @Override            public TreeCell<String> call(TreeView<String> p) {                return new TextFieldTreeCellCustomImpl();            }        });treeView.setPrefHeight(200);return treeView;}private class TextFieldTreeCellCustomImpl extends TreeCell<String> {@Overridepublic void startEdit() {super.startEdit();final TextField textField = new TextField(getItem());/* Define when press the Enter key, the commit edit should be done. */textField.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent arg0) {commitEdit(textField.getText());}});setGraphic(textField);setText(null);}/** * It is fired when the text field loses focus or a Esc key is pressed. * @see javafx.scene.control.TreeCell#cancelEdit() */@Override        public void cancelEdit() {            super.cancelEdit();                        setText(getItem());            setGraphic(getTreeItem().getGraphic());        }/** * In order to render the cell, as the other updateItem() in Cell class, this is called when the creation  * or the change of underlying data (ex. commitEdit(newValue) in Cell). * @see javafx.scene.control.Cell#updateItem(java.lang.Object, boolean) */@Overridepublic void updateItem(String item, boolean empty) {super.updateItem(item, empty);if (item != null) {setGraphic(getTreeItem().getGraphic());setText(getItem());/* Adding a context menu */ContextMenu menu = new ContextMenu();MenuItem addItem = new MenuItem();MenuItem deleteItem = new MenuItem();final TreeItem<String> newItem;if (getTreeItem().getParent() == null) {// root item (first level item)addItem.setText("Add Department");menu.getItems().add(addItem);newItem = new TreeItem<String>("New Department");} else if (getTreeItem().getParent().getParent() == null) {// second level item ("Department")addItem.setText("Add Employee");deleteItem.setText("Delete Department");menu.getItems().addAll(addItem, deleteItem);newItem = new TreeItem<String>("New Employee");} else if (getTreeItem().getParent().getParent().getParent() == null) {// third level item ("Employee")addItem.setText("Add item");deleteItem.setText("Delete Employee");menu.getItems().addAll(addItem, deleteItem);newItem = new TreeItem<String>("New item");} else {addItem.setText("Add child item");deleteItem.setText("Delete item");menu.getItems().addAll(addItem, deleteItem);newItem = new TreeItem<String>("New item");}setContextMenu(menu);addItem.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent arg0) {getTreeItem().getChildren().add(newItem);getTreeView().getSelectionModel().select(newItem);}});deleteItem.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent arg0) {getTreeItem().getParent().getChildren().remove(getTreeItem());}});}}}private class Employee {private String name;private String department;private Employee(String name, String service) {this.name = name;this.department = service;}private String getName() {return name;}private String getDepartment() {return department;}}private Node createSeparatorApp() {Label caption = new Label("Weather Forecast");Label friday = new Label("Friday");Label saturday = new Label("Saturday");Label sunday = new Label("Sunday");GridPane grid = new GridPane();//grid.setGridLinesVisible(true);grid.setPadding(new Insets(10, 10, 10, 10));grid.setVgap(2);grid.setHgap(5);Image cloudImage = new Image(getClass().getResourceAsStream("graphics/cloud.jpg"));Image sunImage = new Image(getClass().getResourceAsStream("graphics/sun.jpg"));caption.setFont(Font.font("Verdana", 20));grid.add(caption, 0, 0, 8, 1);final Separator sepHor = new Separator();sepHor.setId("separator-custom"); sepHor.setPrefHeight(5);grid.add(sepHor, 0, 1, 7, 1);friday.setFont(Font.font("Verdana", 18));grid.add(friday, 0, 2, 2, 1);final Separator sepVert1 = new Separator();sepVert1.setOrientation(Orientation.VERTICAL);grid.add(sepVert1, 2, 2, 1, 2);saturday.setFont(Font.font("Verdana", 18));grid.add(saturday, 3, 2, 2, 1);final Separator sepVert2 = new Separator();sepVert2.setOrientation(Orientation.VERTICAL);grid.add(sepVert2, 5, 2, 1, 2);sunday.setFont(Font.font("Verdana", 18));grid.add(sunday, 6, 2, 2, 1);final ImageView cloud = new ImageView(cloudImage);grid.add(cloud, 0, 3, 1, 1);final Label t1 = new Label("16");t1.setFont(Font.font("Verdana", 20));grid.add(t1, 1, 3, 1, 1);final ImageView sun1 = new ImageView(sunImage);grid.add(sun1, 3, 3, 1, 1);final Label t2 = new Label("18");t2.setFont(Font.font("Verdana", 20));grid.add(t2, 4, 3, 1, 1);final ImageView sun2 = new ImageView(sunImage);grid.add(sun2, 6, 3, 1, 1);final Label t3 = new Label("20");t3.setFont(Font.font("Verdana", 20));grid.add(t3, 7, 3, 1, 1);return grid;}private Node createSliderApp() {Image image = new Image(getClass().getResourceAsStream("graphics/cappuccino.jpg"));final ImageView imageView = new ImageView(image);final SepiaTone sepiaEffect = new SepiaTone();imageView.setEffect(sepiaEffect);Label opacityLevelLabel = new Label("Opacity Level:");opacityLevelLabel.setTextFill(Color.WHITE);Label sepiaToneLabel = new Label("Sepia Tone:");sepiaToneLabel.setTextFill(Color.WHITE);Label scalingFactorLabel = new Label("Scaling Factor:");scalingFactorLabel.setTextFill(Color.WHITE);Slider opacityLevelSlider = new Slider(0, 1, 1);Slider sepiaToneSlider = new Slider(0, 1, 1);Slider scalingFactorSlider = new Slider(0.5, 1, 1);final Label opacityLevelValue = new Label(Double.toString(opacityLevelSlider.getValue()));// Double.toString(double) makes keep one digit after the dot.opacityLevelValue.setTextFill(Color.WHITE);final Label sepiaToneValue = new Label(Double.toString(sepiaToneSlider.getValue()));sepiaToneValue.setTextFill(Color.WHITE);final Label scalingFactorValue = new Label(Double.toString(scalingFactorSlider.getValue()));scalingFactorValue.setTextFill(Color.WHITE);GridPane grid = new GridPane();grid.setStyle("-fx-background-color: black;" +"-fx-background-radius: 5;");//grid.setGridLinesVisible(true);grid.add(imageView, 0, 0, 3, 1);grid.add(opacityLevelLabel, 0, 1);grid.add(opacityLevelSlider, 1, 1);grid.add(opacityLevelValue, 2, 1);grid.add(sepiaToneLabel, 0, 2);grid.add(sepiaToneSlider, 1, 2);grid.add(sepiaToneValue, 2, 2);grid.add(scalingFactorLabel, 0, 3);grid.add(scalingFactorSlider, 1, 3);grid.add(scalingFactorValue, 2, 3);/* adjust the width axis layout */grid.setPrefWidth(image.getWidth());ColumnConstraints col1 = new ColumnConstraints();col1.setMinWidth(ColumnConstraints.CONSTRAIN_TO_PREF);// to avoid that labels in the column shrink in width after the set "grid.setPrefWidth(image.getWidth());" which brings the width of grid pane smaller.ColumnConstraints col2 = new ColumnConstraints();col2.setMinWidth(ColumnConstraints.CONSTRAIN_TO_PREF);ColumnConstraints col3 = new ColumnConstraints();col3.setMinWidth(ColumnConstraints.CONSTRAIN_TO_PREF);grid.getColumnConstraints().addAll(col1, col2, col3);grid.setHgap(70);/* Further enhance the look and feel */grid.setVgap(10);grid.setPadding(new Insets(10, 20, 10, 20));/* Set actions */opacityLevelSlider.valueProperty().addListener(new ChangeListener<Number>() {@Overridepublic void changed(ObservableValue<? extends Number> ov, Number oldNumber, Number newNumber) {opacityLevelValue.setText(String.format("%.2f", newNumber));// allows two digits after the dot.imageView.setOpacity(newNumber.doubleValue());}});sepiaToneSlider.valueProperty().addListener(new ChangeListener<Number>() {@Overridepublic void changed(ObservableValue<? extends Number> ov, Number oldNumber, Number newNumber) {sepiaToneValue.setText(String.format("%.2f", newNumber));sepiaEffect.setLevel(newNumber.doubleValue());}});scalingFactorSlider.valueProperty().addListener(new ChangeListener<Number>() {@Overridepublic void changed(ObservableValue<? extends Number> ov, Number oldNumber, Number newNumber) {scalingFactorValue.setText(String.format("%.2f", newNumber));imageView.setScaleX(newNumber.doubleValue());imageView.setScaleY(newNumber.doubleValue());}});return grid;}private Node createProgressApp() {final HBox hBox = new HBox();hBox.getStyleClass().add("hbox");hBox.setId("hobx-progress");hBox.setMaxHeight(Region.USE_PREF_SIZE);final ProgressBar progressBar = new ProgressBar(0);final ProgressIndicator progressIndicator = new ProgressIndicator(0);/* Creating a typical slider */final Slider slider = new Slider();slider.setMin(0);slider.setMax(1);// the actual value is 0 by defaultslider.setShowTickLabels(true);slider.setShowTickMarks(true);slider.setMajorTickUnit(0.5);slider.setMinorTickCount(4);slider.setBlockIncrement(0.1);slider.setSnapToTicks(true);// keep the slider's value aligned with the tick marks.final Label value = new Label(String.format("%.2f", slider.getValue()));slider.valueProperty().addListener(new ChangeListener<Number>() {@Overridepublic void changed(ObservableValue<? extends Number> ov, Number oldNumber, Number newNumber) {if (slider.isValueChanging()) {value.setText("value changing...");HBox.setMargin(value, new Insets(0, -41, 0, -42));// because the text is longerprogressBar.setProgress(ProgressIndicator.INDETERMINATE_PROGRESS);progressIndicator.setProgress(ProgressIndicator.INDETERMINATE_PROGRESS);} else {value.setText(String.format("%.2f", newNumber));// allows two digits after the dot.HBox.setMargin(value, new Insets(0, 0, 0, 0));// return to zero marginprogressBar.setProgress(newNumber.doubleValue());progressIndicator.setProgress(newNumber.doubleValue());}}});hBox.getChildren().addAll(slider, value, progressBar, progressIndicator);return hBox;}private Node createHyperlinkApp() {final WebView webView = new WebView();final double initialWebViewPrefHeight = webView.getPrefHeight();//System.out.println(webView.getPrefWidth());webView.setPrefHeight(0);final WebEngine webEngine = webView.getEngine();final Worker<Void> worker = webEngine.getLoadWorker();final Label message = new Label();message.setPrefWidth(Double.MAX_VALUE);// Initialize the preferred width of an empty labelmessage.setId("label-web-message");final ProgressBar progressBar = new ProgressBar();progressBar.setVisible(false);final GridPane grid = new GridPane() {@Override protected void layoutChildren() {super.layoutChildren();                                message.autosize();                message.setLayoutX(0);                message.setLayoutY(getHeight() - message.getLayoutBounds().getHeight());                                progressBar.autosize();                progressBar.setLayoutX(getWidth() - progressBar.getLayoutBounds().getWidth());                progressBar.setLayoutY(getHeight() - progressBar.getLayoutBounds().getHeight());                           }};//grid.setGridLinesVisible(true);//grid.setStyle("-fx-background-color: red;");// just for debugginggrid.getStyleClass().add("grid");String[] captions = new String[] {"Products", "Education", "Partners", "Support"};String[] imageFiles =new String[] {"product.png", "education.png", "partners.png", "support.png"};final String[] urls = new String[] {"http://www.oracle.com/us/products/index.html",        "http://education.oracle.com/",        "http://www.oracle.com/partners/index.html",        "http://www.oracle.com/us/support/index.html"};final Hyperlink[] hyperlinks = new Hyperlink[captions.length]; // declare but not initializationfinal SimpleBooleanProperty clicked = new SimpleBooleanProperty(false);for (int i = 0; i < captions.length; i++) {hyperlinks[i] = new Hyperlink(captions[i]);// initializationhyperlinks[i].setFont(Font.font("Arial", 14));hyperlinks[i].setGraphic(new ImageView(new Image(getClass().getResourceAsStream("graphics/" + imageFiles[i]))));final int iTemp = i;hyperlinks[i].setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent event) {/* Brings the top-left corner of the grid to the top-left corner of the scroll pane's view port *//* Method 1: *///double contentH = ((FlowPane) scrollPane.getContent()).getHeight();//double viewH = scrollPane.getViewportBounds().getHeight();//double needsPositionY = grid.getLayoutY();//if (needsPositionY > (contentH - viewH)) {//((FlowPane) scrollPane.getContent()).heightProperty().addListener(new ChangeListener<Number>() {////@Override//public void changed(ObservableValue<? extends Number> ov, Number oldNumber, Number newNumber) {//if ((newNumber.doubleValue() - oldNumber.doubleValue()) == initialWebViewPrefHeight) {//double contentH = ((FlowPane) scrollPane.getContent()).getHeight();//double viewH = scrollPane.getViewportBounds().getHeight();//double needsPositionY = grid.getLayoutY();//scrollPane.setVvalue(needsPositionY / (contentH - viewH));//((FlowPane) scrollPane.getContent()).heightProperty().removeListener(this);//}//}////});////}//scrollPane.setVvalue(needsPositionY / (contentH - viewH));/* Method 2: *///scrollPane.vmaxProperty().addListener(new ChangeListener<Number>() {////@Override//public void changed(ObservableValue<? extends Number> ov, Number oldNumber, Number newNumber) {//scrollPane.setVvalue(grid.getLayoutY());//scrollPane.vmaxProperty().removeListener(this);// make the listener valid only in the current action event.//}////});//scrollPane.setVvalue(grid.getLayoutY());/* Brings the bottom-left corner of the grid to the bottom-left corner of the scroll pane's view port */double contentH = ((FlowPane) scrollPane.getContent()).getHeight();double viewH = scrollPane.getViewportBounds().getHeight();double needsPositionY;if (!clicked.get()) {needsPositionY = grid.getLayoutY() + grid.getHeight() + initialWebViewPrefHeight;if (needsPositionY > contentH) {((FlowPane) scrollPane.getContent()).heightProperty().addListener(new ChangeListener<Number>() {@Overridepublic void changed(ObservableValue<? extends Number> ov, Number oldNumber, Number newNumber) {if ((newNumber.doubleValue() - oldNumber.doubleValue()) == initialWebViewPrefHeight) {double needsPositionY = grid.getLayoutY() + grid.getHeight() + initialWebViewPrefHeight;double contentH = ((FlowPane) scrollPane.getContent()).getHeight();double viewH = scrollPane.getViewportBounds().getHeight();scrollPane.setVvalue((needsPositionY - viewH) / (contentH - viewH));((FlowPane) scrollPane.getContent()).heightProperty().removeListener(this);}}});}} else {needsPositionY = grid.getLayoutY() + grid.getHeight();}clicked.set(true);scrollPane.setVvalue((needsPositionY - viewH) / (contentH - viewH));webView.setPrefHeight(initialWebViewPrefHeight);webEngine.load(urls[iTemp]);message.setText(worker.getMessage());message.setPrefWidth(Control.USE_COMPUTED_SIZE);message.setVisible(true);worker.messageProperty().addListener(new ChangeListener<String>() {@Overridepublic void changed(ObservableValue<? extends String> ov, String oldString, String newString) {if (!newString.isEmpty() && newString != null) {message.setText(newString);}}});progressBar.setVisible(true);worker.progressProperty().addListener(new ChangeListener<Number>() {@Overridepublic void changed(ObservableValue<? extends Number> ov, Number oldNumber, Number newNumber) {progressBar.setProgress(newNumber.doubleValue());if (newNumber.doubleValue() == 1.0) {progressBar.setVisible(false);Timeline timeLine = new Timeline();timeLine.getKeyFrames().addAll(new KeyFrame(Duration.ZERO, new KeyValue(message.visibleProperty(), true)),new KeyFrame(Duration.seconds(1), new KeyValue(message.visibleProperty(), false)));timeLine.play();} else if (oldNumber.doubleValue() == 1.0) {progressBar.setVisible(true);message.setVisible(true);}}});}});}Button refreshLinks = new Button("Refresh links");refreshLinks.setId("button-custom-2");refreshLinks.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent arg0) {for (Hyperlink hyperlink : hyperlinks) {hyperlink.setVisited(false);}webView.setPrefHeight(0);clicked.set(false);worker.cancel();progressBar.setVisible(false);Timeline timeLine = new Timeline();timeLine.getKeyFrames().addAll(new KeyFrame(Duration.ZERO, new KeyValue(message.visibleProperty(), true)),new KeyFrame(Duration.seconds(1), new KeyValue(message.visibleProperty(), false)));timeLine.play();}});for (int i = 0; i < captions.length; i++) {grid.add(hyperlinks[i], i, 0);}grid.add(refreshLinks, captions.length, 0);grid.add(webView, 0, 1, 5, 1);message.setManaged(false);grid.getChildren().add(message);progressBar.setManaged(false);grid.getChildren().add(progressBar);GridPane.setHalignment(refreshLinks, HPos.RIGHT);GridPane.setMargin(refreshLinks, new Insets(0, 10, 0, 0));return grid;}private Node createTitledPaneAccordionApp() {HBox hBox = new HBox();hBox.setMaxHeight(Region.USE_PREF_SIZE);/* The titled pane is resized to accommodate the preferred size of its content. * Do not explicitly set the minimal, maximum, or preferred height of a titled pane,  * as this may lead to unexpected behavior when the titled pane is opened or closed. */TitledPane tp = new TitledPane();GridPane grid = new GridPane();Label labelTo = new Label("To:");TextField tfTo = new TextField();Label labelCc = new Label("Cc:");TextField tfCc = new TextField();Label labelSubject = new Label("Subject:");TextField tfSubject = new TextField();Label labelAttachment = new Label("Attachment:");final Label valueAttachment = new Label("N/A");grid.add(labelTo, 0, 0);grid.add(tfTo, 1, 0);grid.add(labelCc, 0, 1);grid.add(tfCc, 1, 1);grid.add(labelSubject, 0, 2);grid.add(tfSubject, 1, 2);grid.add(labelAttachment, 0, 3);grid.add(valueAttachment, 1, 3);tp.setContent(grid);tp.setText("Grid");/* Do not explicitly set the minimal, maximum, or preferred height of an accordion,  * as this may lead to unexpected behavior when one of its titled pane is opened. */Accordion accordion = new Accordion();String[] imageNames = new String[]{"Apples", "Flowers", "Leaves"};Image[] images = new Image[imageNames.length];ImageView[] imageViews = new ImageView[imageNames.length];TitledPane[] tps = new TitledPane[imageNames.length];for (int i = 0; i < imageNames.length; i++) {images[i] = new Image(getClass().getResourceAsStream("graphics/" + imageNames[i] + ".jpg"));imageViews[i] = new ImageView(images[i]);tps[i] = new TitledPane(imageNames[i], imageViews[i]);accordion.getPanes().add(tps[i]);}/* Set actions */accordion.expandedPaneProperty().addListener(new ChangeListener<TitledPane>() {@Overridepublic void changed(ObservableValue<? extends TitledPane> ov, TitledPane oldTp, TitledPane newTp) {if (newTp != null) {valueAttachment.setText(newTp.getText() + ".jpg");}}});hBox.getChildren().addAll(tp, accordion);return hBox;}private Node createMenuBarApp() {/* Define data model */final Page[] pages = new Page[] {new Page("Apple","Malus domestica","Apple","The apple is the pomaceous fruit of the apple tree, species Malus " +"domestica in the rose family (Rosaceae). It is one of the most " +"widely cultivated tree fruits, and the most widely known of " +"the many members of genus Malus that are used by humans. " +"The tree originated in Western Asia, where its wild ancestor, " +"the Alma, is still found today."),new Page("Hawthorn","Crataegus monogyna","Hawthorn","The hawthorn is a large genus of shrubs and trees in the rose " +"family, Rosaceae, native to temperate regions of the Northern " +"Hemisphere in Europe, Asia and North America. " +"The name hawthorn was " +"originally applied to the species native to northern Europe, " +"especially the Common Hawthorn C. monogyna, and the unmodified " +"name is often so used in Britain and Ireland."),new Page("Ivy","Parthenocissus tricuspidata","Ivy","The ivy is a flowering plant in the grape family (Vitaceae) native to " +"eastern Asia in Japan, Korea, and northern and eastern China. " +"It is a deciduous woody vine growing to 30 m tall or more given " +"suitable support,  attaching itself by means of numerous small " +"branched tendrils tipped with sticky disks."),new Page("Quince","Cydonia oblonga","Quince","The quince is the sole member of the genus Cydonia and is native to " + "warm-temperate southwest Asia in the Caucasus region. The " +"immature fruit is green with dense grey-white pubescence, most " +"of which rubs off before maturity in late autumn when the fruit " +"changes color to yellow with hard, strongly perfumed flesh.")};final VBox vBox = new VBox();vBox.setStyle("-fx-background-color: red;");// for debuggingvBox.setMaxHeight(Region.USE_PREF_SIZE);// the vertical box is not extensibleMenuBar menuBar = new MenuBar();Menu fileMenu = new Menu("File");MenuItem shuffle = new MenuItem("Shuffle");shuffle.setGraphic(new ImageView(new Image(getClass().getResourceAsStream("graphics/new.png"))));MenuItem clear = new MenuItem("Clear");clear.setAccelerator(new KeyCodeCombination(KeyCode.X, KeyCombination.CONTROL_DOWN));SeparatorMenuItem separator = new SeparatorMenuItem();MenuItem exit = new MenuItem("Exit");fileMenu.getItems().addAll(shuffle, clear, separator, exit);Menu editMenu = new Menu("Edit");Menu picEffect = new Menu("Picture Effect");RadioMenuItem sepiaTone = new RadioMenuItem("Sepia Tone");sepiaTone.setUserData(new SepiaTone());RadioMenuItem glow = new RadioMenuItem("Glow");glow.setUserData(new Glow());RadioMenuItem shadow = new RadioMenuItem("Shadow");shadow.setUserData(new DropShadow());final ToggleGroup tg = new ToggleGroup();sepiaTone.setToggleGroup(tg);glow.setToggleGroup(tg);shadow.setToggleGroup(tg);picEffect.getItems().addAll(sepiaTone, glow, shadow);final MenuItem noEffects = new MenuItem("No Effects");noEffects.setDisable(true);editMenu.getItems().addAll(picEffect, noEffects);Menu viewMenu = new Menu("View");CheckMenuItem titleMenuItem = new CheckMenuItem("Title");titleMenuItem.setSelected(true);CheckMenuItem binomialNameMenuItem = new CheckMenuItem("Binomial name");binomialNameMenuItem.setSelected(true);CheckMenuItem pictureMenuItem = new CheckMenuItem("Picture");pictureMenuItem.setSelected(true);CheckMenuItem descriptionMenuItem = new CheckMenuItem("Description");descriptionMenuItem.setSelected(true);viewMenu.getItems().addAll(titleMenuItem, binomialNameMenuItem, pictureMenuItem, descriptionMenuItem);menuBar.getMenus().addAll(fileMenu, editMenu, viewMenu);final Label title = new Label();title.setUserData(0);title.setFont(new Font("Verdana Bold", 22));final Label binomialName = new Label();binomialName.setUserData(1);binomialName.setFont(new Font("Arial Italic", 10));final ImageView picture = new ImageView();picture.setUserData(2);picture.setFitHeight(150);picture.setPreserveRatio(true);final Label description = new Label();description.setUserData(3);description.setPrefWidth(400);description.setWrapText(true);description.setTextAlignment(TextAlignment.JUSTIFY);shuffle(pages, title, binomialName, picture, description);final VBox pageLayout = new VBox();pageLayout.getStyleClass().add("vbox");pageLayout.getChildren().addAll(title, binomialName, picture, description);vBox.getChildren().addAll(menuBar, pageLayout);/* Define actions */shuffle.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent event) {shuffle(pages, title, binomialName, picture, description);scrollToBottom(vBox);if (!vBox.getChildren().contains(pageLayout)) {vBox.getChildren().add(pageLayout);}}});clear.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent event) {vBox.getChildren().remove(pageLayout);}});exit.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent event) {//Platform.exit();mainContainer.getChildren().remove(vBox);}});tg.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {@Overridepublic void changed(ObservableValue<? extends Toggle> ov, Toggle oldToggle, Toggle newToggle) {if (newToggle != null) {picture.setEffect((Effect) newToggle.getUserData());noEffects.setDisable(false);} else {noEffects.setDisable(true);}}});noEffects.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent event) {picture.setEffect(null);tg.getSelectedToggle().setSelected(false);}});titleMenuItem.selectedProperty().addListener(new CheckMenuItemChangeListener(title, pageLayout));binomialNameMenuItem.selectedProperty().addListener(new CheckMenuItemChangeListener(binomialName, pageLayout));pictureMenuItem.selectedProperty().addListener(new CheckMenuItemChangeListener(picture, pageLayout));descriptionMenuItem.selectedProperty().addListener(new CheckMenuItemChangeListener(description, pageLayout));/* add context menu */final ContextMenu contextMenu = new ContextMenu();MenuItem copy = new MenuItem("Copy Image");MenuItem save = new MenuItem("Save Image");contextMenu.getItems().addAll(copy, save);picture.setOnMouseClicked(new EventHandler<MouseEvent>() {@Overridepublic void handle(MouseEvent event) {if (event.getButton() == MouseButton.SECONDARY) {contextMenu.show(picture, event.getScreenX(), event.getScreenY());}}});copy.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent event) {Clipboard clipboard = Clipboard.getSystemClipboard();ClipboardContent content = new ClipboardContent();content.putImage(picture.getImage());clipboard.setContent(content);}});save.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent event) {FileChooser fileChooser = new FileChooser();fileChooser.setTitle("Save Image");fileChooser.setInitialDirectory(new File(System.getProperty("user.home")));fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("All Images", "*.*"),new FileChooser.ExtensionFilter("JPG", "*.jpg"),new FileChooser.ExtensionFilter("PNG", "*.png"));File file = fileChooser.showSaveDialog(vBox.getScene().getWindow());if (file != null) {try {ImageIO.write(SwingFXUtils.fromFXImage(picture.getImage(), null), "png", file);// The input image format is "jpg".} catch (IOException e) {e.printStackTrace();}}}});return vBox;}private void shuffle(Page[] pages, Label title, Label binomialName, ImageView picture, Label description) {int index = currentIndex;while (index == currentIndex) {index = (int) (Math.random() * pages.length);}currentIndex =  index;title.setText(pages[index].getTitle());binomialName.setText("(" + pages[index].getBinomialName() + ")");picture.setImage(new Image(getClass().getResource("graphics/" + pages[index].getPictureName() + ".jpg").toExternalForm(), true));description.setText(pages[index].getDescription());}private class Page {private String title;private String binomialName;private String pictureName;private String description;Page (String title, String binomialName, String pictureName, String description) {this.title = title;this.binomialName = binomialName;this.pictureName = pictureName;this.description = description;}String getTitle() {return title;}String getBinomialName() {return binomialName;}String getPictureName() {return pictureName;}String getDescription() {return description;}}private class CheckMenuItemChangeListener implements ChangeListener<Boolean> {private Node item;private Pane layout;CheckMenuItemChangeListener(Node item, Pane layout) {this.item = item;this.layout = layout;}@Overridepublic void changed(ObservableValue<? extends Boolean> ov, Boolean old_boolean, Boolean new_boolean) {if (new_boolean) {/* add the imageView to the observable list in order */if (!layout.getChildren().isEmpty()) {Object[] nodes = layout.getChildren().toArray();int k;for (k = 0; k < nodes.length; k++) {if ((int) item.getUserData() < (int) ((Node) nodes[k]).getUserData()) {layout.getChildren().add(k, item);break;}}if (k == nodes.length) {layout.getChildren().add(k, item);}} else {layout.getChildren().add(item);}} else {/* simply remove the node */layout.getChildren().remove(item);}scrollToBottom((VBox) layout.getParent());}}/** * When there is variation on the content height of the scroll pane, and the bottom of  * the region exceeds the bottom of viewport, we scroll to that the bottom of the region  * is at the bottom of the viewport of scroll pane. * <p> * Note that the height variation of the content of scroll pane is earlier than that of  * region (done by test of height property listener).  * @param region - the region contained <b>directly</b> in the scroll pane */private void scrollToBottom(final Region region) {region.heightProperty().addListener(new ChangeListener<Number>() {@Overridepublic void changed(ObservableValue<? extends Number> ov, Number oldNumber, Number newNumber) {double contentH = mainContainer.getHeight();// the new valuedouble viewH = scrollPane.getViewportBounds().getHeight();double viewportBottomY = viewH - scrollPane.getViewportBounds().getMinY();double needsPositionY = region.getLayoutY() + newNumber.doubleValue();if (needsPositionY <= viewportBottomY) {// do nothing} else {scrollPane.setVvalue((needsPositionY - viewH) / (contentH - viewH));}mainContainer.heightProperty().removeListener(this);}});}private Node createColorPickerApp() {ToolBar toolBar = new ToolBar();final ComboBox<String> shirtIcon = new ComboBox<String>(FXCollections.observableArrayList("Oracle", "Java", "JavaFX", "Cup"));shirtIcon.setTooltip(new Tooltip("T-shirt icon"));shirtIcon.setValue("Oracle");final ColorPicker bgColor = new ColorPicker(Color.web("#ccffcc"));bgColor.setId("color-picker-custom");bgColor.setTooltip(new Tooltip("Background color"));final ColorPicker shadowColor = new ColorPicker(Color.BLACK);shadowColor.getStyleClass().addAll("button");shadowColor.setTooltip(new Tooltip("Shadow color"));final ColorPicker shirtColor = new ColorPicker(Color.web("#ffffb3"));shirtColor.getStyleClass().add("split-button");shirtColor.setId("color-picker-custom-2");shirtColor.setTooltip(new Tooltip("T-shirt color"));toolBar.getItems().addAll(shirtIcon, bgColor, shadowColor, shirtColor);final DropShadow dropShadow = new DropShadow();dropShadow.setColor(shadowColor.getValue());StackPane stack = new StackPane();final SVGPath svg = new SVGPath();svg.setContent("m 118,331.36218 46,0 14.05385,52.44968 14.06458,-52.48974 42.88157,0 62,47.04006 -26,27 -16,-17 -1,148 -155,2 2,-149 -20,20 -25,-26 z");svg.setStroke(Color.DARKGRAY);svg.setStrokeWidth(2);svg.setEffect(dropShadow);svg.setFill(shirtColor.getValue());final ImageView logo = new ImageView(new Image(getClass().getResourceAsStream("graphics/" + shirtIcon.getValue() + "Logo.png")));stack.getChildren().addAll(svg, logo);final VBox vBox = new VBox();vBox.getStyleClass().add("vbox");// CSS priority lowvBox.setId("vbox-custom");// CSS priority mediumColor color = bgColor.getValue();int red = (int) (color.getRed() * 100);int green = (int) (color.getGreen() * 100);int blue = (int) (color.getBlue() * 100);String bgColorCSS = "-fx-background-color: rgb(" + red + "%," + green + "%," + blue + "%);";vBox.setStyle(bgColorCSS);// CSS priority highvBox.getChildren().addAll(toolBar, stack);/* set actions */shirtIcon.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {@Overridepublic void changed(ObservableValue<? extends String> ov, String oldValue, String newValue) {logo.setImage(new Image(getClass().getResourceAsStream("graphics/" + newValue + "Logo.png")));}});bgColor.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent arg0) {Color color = bgColor.getValue();int red = (int) (color.getRed() * 100);int green = (int) (color.getGreen() * 100);int blue = (int) (color.getBlue() * 100);String bgColorCSS = "-fx-background-color: rgb(" + red + "%," + green + "%," + blue + "%);";vBox.setStyle(bgColorCSS);}});shadowColor.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent arg0) {dropShadow.setColor(shadowColor.getValue());}});shirtColor.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent arg0) {svg.setFill(shirtColor.getValue());}});return vBox;}private Node createPaginationApp() {final int itemsPerPage = 15;final Object[] fonts = Font.getFontNames().toArray();Pagination pagination = new Pagination((fonts.length / itemsPerPage) + 1, 0);pagination.getStyleClass().add(Pagination.STYLE_CLASS_BULLET);pagination.setId("pagination-custom");pagination.setPageFactory(new Callback<Integer, Node>() {@Overridepublic Node call(Integer pageIndex) {return createPage(pageIndex, itemsPerPage, fonts);}});return pagination;}private VBox createPage(int pageIndex, int itemsPerPage, Object[] fonts) {VBox vBox = new VBox();vBox.getStyleClass().add("vbox");vBox.setId("vbox-custom-2");int pageStartIndex = pageIndex * itemsPerPage;for (int i = pageStartIndex; i < pageStartIndex + itemsPerPage; i++) {if (i < fonts.length) {Label label = new Label(fonts[i].toString());vBox.getChildren().add(label);} else {break;}}return vBox;}}

原创粉丝点击