300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > JavaFX开发桌面 移动端 嵌入式权威指南(二)—— 如何应用JavaFX开发用户界面

JavaFX开发桌面 移动端 嵌入式权威指南(二)—— 如何应用JavaFX开发用户界面

时间:2020-02-26 21:35:53

相关推荐

JavaFX开发桌面 移动端 嵌入式权威指南(二)—— 如何应用JavaFX开发用户界面

目录

概述编程与声明创建用户界面以节点为中心的UI的简介 确定舞台是否处于焦点位置控制舞台的z轴顺序设置场景中的光标通过ID找到场景中的节点从场景访问舞台向场景内容序列中插入节点场景中用CSS来修饰节点处理输入事件 场景中的动画节点为动画使用时间线为时间线插入KeyFrame控制时间线

概述

JavaFX是用于构建富互联网应用程序的Java库。使用JavaFX开发的应用程序可以在各种设备上运行,如台式计算机,手机,物联网

设备,平板电脑等。这一章主要是介绍如何应用JavaFX使用编程声明方式开发用户界面。

编程与声明创建用户界面

以节点为中心的UI的简介

package sample;import java.util.List;import javafx.application.Application;import javafx.beans.property.SimpleStringProperty;import javafx.beans.property.StringProperty;import javafx.geometry.Rectangle2D;import javafx.geometry.VPos;import javafx.scene.Group;import javafx.scene.Scene;import javafx.scene.control.Button;import javafx.scene.control.CheckBox;import javafx.scene.control.Label;import javafx.scene.control.TextField;import javafx.scene.input.MouseEvent;import javafx.scene.layout.HBox;import javafx.scene.layout.VBox;import javafx.scene.paint.Color;import javafx.scene.shape.Rectangle;import javafx.scene.text.Text;import javafx.stage.Screen;import javafx.stage.Stage;import javafx.stage.StageStyle;import javafx.stage.WindowEvent;public class StageCoachMain extends Application {StringProperty title = new SimpleStringProperty();Text textStageX;Text textStageY;Text textStageW;Text textStageH;Text textStageF;CheckBox checkBoxResizable;CheckBox checkBoxFullScreen;double dragAnchorX;double dragAnchorY;public static void main(String[] args) {Application.launch(args);}@Overridepublic void start(Stage stage) {//设置舞台StageStyle stageStyle = StageStyle.DECORATED;List<String> unnamedParams = getParameters().getUnnamed();if (unnamedParams.size() > 0) {String stageStyleParam = unnamedParams.get(0);if (stageStyleParam.equalsIgnoreCase("transparent")) {stageStyle = StageStyle.TRANSPARENT;} else if (stageStyleParam.equalsIgnoreCase("undecorated")) {stageStyle = StageStyle.UNDECORATED;} else if (stageStyleParam.equalsIgnoreCase("utility")) {stageStyle = StageStyle.UTILITY;}}final Stage stageRef = stage;Group rootGroup;TextField titleTextField;Button toBackButton = new Button("toBack()");toBackButton.setOnAction(e -> stageRef.toBack());Button toFrontButton = new Button("toFront()");toFrontButton.setOnAction(e -> stageRef.toFront());Button closeButton = new Button("close()");//关闭舞台并检测何时关闭closeButton.setOnAction(e -> stageRef.close());//绘制圆弧矩形Rectangle blue = new Rectangle(250, 350, Color.SKYBLUE);blue.setArcHeight(50);blue.setArcWidth(50);textStageX = new Text();textStageX.setTextOrigin(VPos.TOP);textStageY = new Text();textStageY.setTextOrigin(VPos.TOP);textStageH = new Text();textStageH.setTextOrigin(VPos.TOP);textStageW = new Text();textStageW.setTextOrigin(VPos.TOP);textStageF = new Text();textStageF.setTextOrigin(VPos.TOP);checkBoxResizable = new CheckBox("resizable");checkBoxResizable.setDisable(stageStyle == StageStyle.TRANSPARENT|| stageStyle == StageStyle.UNDECORATED);checkBoxFullScreen = new CheckBox("fullScreen");titleTextField = new TextField("Stage Coach");Label titleLabel = new Label("title");//使用UI布局容器HBox titleBox = new HBox(titleLabel, titleTextField);VBox contentBox = new VBox(textStageX, textStageY, textStageW, textStageH, textStageF,checkBoxResizable, checkBoxFullScreen,titleBox, toBackButton, toFrontButton, closeButton);contentBox.setLayoutX(30);contentBox.setLayoutY(20);contentBox.setSpacing(10);rootGroup = new Group(blue, contentBox);//用节点填充场景Scene scene = new Scene(rootGroup, 270, 370);//设置场景中背景scene.setFill(Color.TRANSPARENT);//when mouse button is pressed, save the initial position of screenrootGroup.setOnMousePressed((MouseEvent me) -> {dragAnchorX = me.getScreenX() - stageRef.getX();dragAnchorY = me.getScreenY() - stageRef.getY();});//when screen is dragged, translate it accordinglyrootGroup.setOnMouseDragged((MouseEvent me) -> {stageRef.setX(me.getScreenX() - dragAnchorX);stageRef.setY(me.getScreenY() - dragAnchorY);});textStageX.textProperty().bind(new SimpleStringProperty("x: ").concat(stageRef.xProperty().asString()));textStageY.textProperty().bind(new SimpleStringProperty("y: ").concat(stageRef.yProperty().asString()));textStageW.textProperty().bind(new SimpleStringProperty("width: ").concat(stageRef.widthProperty().asString()));textStageH.textProperty().bind(new SimpleStringProperty("height: ").concat(stageRef.heightProperty().asString()));textStageF.textProperty().bind(new SimpleStringProperty("focused: ").concat(stageRef.focusedProperty().asString()));//控制舞台是否可以改变大小stage.setResizable(true);checkBoxResizable.selectedProperty().bindBidirectional(stage.resizableProperty());// 让舞台全屏checkBoxFullScreen.selectedProperty().addListener((ov, oldValue, newValue) -> {stageRef.setFullScreen(checkBoxFullScreen.selectedProperty().getValue());});title.bind(titleTextField.textProperty());stage.setScene(scene);stage.titleProperty().bind(title);stage.initStyle(stageStyle);//关闭舞台并检测何时关闭stage.setOnCloseRequest((WindowEvent we) -> {System.out.println("Stage is closing");});stage.show();//使用用户界面布局容器Rectangle2D primScreenBounds = Screen.getPrimary().getVisualBounds();stage.setX((primScreenBounds.getWidth() - stage.getWidth()) / 2);stage.setY((primScreenBounds.getHeight() - stage.getHeight()) / 4);}}

确定舞台是否处于焦点位置

textStageF.textProperty().bind(new SimpleStringProperty("focused: ")

.concat(stageRef.focusedProperty().asString()));

控制舞台的z轴顺序

Button toBackButton = new Button(“toBack()”);

toBackButton.setOnAction(e -> stageRef.toBack());

Button toFrontButton = new Button(“toFront()”);

toFrontButton.setOnAction(e -> stageRef.toFront());

package sample;/*** @author: Administrator* @date: /03/17 22:02* @description:*/import javafx.application.Application;import javafx.beans.property.DoubleProperty;import javafx.beans.property.SimpleDoubleProperty;import javafx.beans.property.SimpleStringProperty;import javafx.collections.FXCollections;import javafx.collections.ObservableList;import javafx.geometry.HPos;import javafx.geometry.Insets;import javafx.geometry.Orientation;import javafx.geometry.VPos;import javafx.scene.Cursor;import javafx.scene.Scene;import javafx.scene.control.ChoiceBox;import javafx.scene.control.Hyperlink;import javafx.scene.control.Label;import javafx.scene.control.RadioButton;import javafx.scene.control.Slider;import javafx.scene.control.ToggleGroup;import javafx.scene.layout.FlowPane;import javafx.scene.layout.HBox;import javafx.scene.paint.Color;import javafx.scene.text.Font;import javafx.scene.text.FontWeight;import javafx.scene.text.Text;import javafx.stage.Stage;public class OnTheSceneMain extends Application {DoubleProperty fillVals = new SimpleDoubleProperty(255.0);Scene sceneRef;ObservableList cursors = FXCollections.observableArrayList(Cursor.DEFAULT,Cursor.CROSSHAIR,Cursor.WAIT,Cursor.TEXT,Cursor.HAND,Cursor.MOVE,Cursor.N_RESIZE,Cursor.NE_RESIZE,Cursor.E_RESIZE,Cursor.SE_RESIZE,Cursor.S_RESIZE,Cursor.SW_RESIZE,Cursor.W_RESIZE,Cursor.NW_RESIZE,Cursor.NONE);public static void main(String[] args) {Application.launch(args);}@Overridepublic void start(Stage stage) {Slider sliderRef;ChoiceBox choiceBoxRef;Text textSceneX;Text textSceneY;Text textSceneW;Text textSceneH;Label labelStageX;Label labelStageY;Label labelStageW;Label labelStageH;final ToggleGroup toggleGrp = new ToggleGroup();sliderRef = new Slider(0, 255, 255);sliderRef.setOrientation(Orientation.VERTICAL);choiceBoxRef = new ChoiceBox(cursors);HBox hbox = new HBox(sliderRef, choiceBoxRef);hbox.setSpacing(10);textSceneX = new Text();textSceneX.getStyleClass().add("emphasized-text");textSceneY = new Text();textSceneY.getStyleClass().add("emphasized-text");textSceneW = new Text();textSceneW.getStyleClass().add("emphasized-text");textSceneH = new Text();textSceneH.getStyleClass().add("emphasized-text");textSceneH.setId("sceneHeightText");Hyperlink hyperlink = new Hyperlink("lookup");hyperlink.setOnAction((javafx.event.ActionEvent e) -> {System.out.println("sceneRef:" + sceneRef);Text textRef = (Text) sceneRef.lookup("#sceneHeightText");System.out.println(textRef.getText());});RadioButton radio1 = new RadioButton("onTheScene.css");radio1.setSelected(true);radio1.setToggleGroup(toggleGrp);RadioButton radio2 = new RadioButton("changeOfScene.css");radio2.setToggleGroup(toggleGrp);labelStageX = new Label();labelStageX.setId("stageX");labelStageY = new Label();labelStageY.setId("stageY");labelStageW = new Label();labelStageH = new Label();FlowPane sceneRoot = new FlowPane(Orientation.VERTICAL, 20, 10, hbox,textSceneX, textSceneY, textSceneW, textSceneH, hyperlink,radio1, radio2,labelStageX, labelStageY,labelStageW,labelStageH);sceneRoot.setPadding(new Insets(0, 20, 40, 0));sceneRoot.setColumnHalignment(HPos.LEFT);sceneRoot.setLayoutX(20);sceneRoot.setLayoutY(40);sceneRef = new Scene(sceneRoot, 600, 250);sceneRef.getStylesheets().add("onTheScene.css");stage.setScene(sceneRef);choiceBoxRef.getSelectionModel().selectFirst();// Setup various property bindingtextSceneX.textProperty().bind(new SimpleStringProperty("Scene x: ").concat(sceneRef.xProperty().asString()));textSceneY.textProperty().bind(new SimpleStringProperty("Scene y: ").concat(sceneRef.yProperty().asString()));textSceneW.textProperty().bind(new SimpleStringProperty("Scene width: ").concat(sceneRef.widthProperty().asString()));textSceneH.textProperty().bind(new SimpleStringProperty("Scene height: ").concat(sceneRef.heightProperty().asString()));labelStageX.textProperty().bind(new SimpleStringProperty("Stage x: ").concat(sceneRef.getWindow().xProperty().asString()));labelStageY.textProperty().bind(new SimpleStringProperty("Stage y: ").concat(sceneRef.getWindow().yProperty().asString()));labelStageW.textProperty().bind(new SimpleStringProperty("Stage width: ").concat(sceneRef.getWindow().widthProperty().asString()));labelStageH.textProperty().bind(new SimpleStringProperty("Stage height: ").concat(sceneRef.getWindow().heightProperty().asString()));sceneRef.cursorProperty().bind(choiceBoxRef.getSelectionModel().selectedItemProperty());fillVals.bind(sliderRef.valueProperty());// When fillVals changes, use that value as the RGB to fill the scenefillVals.addListener((ov, oldValue, newValue) -> {Double fillValue = fillVals.getValue() / 256.0;sceneRef.setFill(new Color(fillValue, fillValue, fillValue, 1.0));});// When the selected radio button changes, set the appropriate style sheettoggleGrp.selectedToggleProperty().addListener((ov, oldValue, newValue) -> {String radioButtonText = ((RadioButton) toggleGrp.getSelectedToggle()).getText();sceneRef.getStylesheets().clear();sceneRef.getStylesheets().addAll(radioButtonText);});stage.setTitle("On the Scene");stage.show();// Define an unmanaged node that will display TextText addedTextRef = new Text(0, -30, "");addedTextRef.setTextOrigin(VPos.TOP);addedTextRef.setFill(Color.BLUE);addedTextRef.setFont(Font.font("Sans Serif", FontWeight.BOLD, 16));addedTextRef.setManaged(false);// Bind the text of the added Text node to the fill property of the SceneaddedTextRef.textProperty().bind(new SimpleStringProperty("Scene fill: ").concat(sceneRef.fillProperty()));// Add to the Text node to the FlowPane((FlowPane) sceneRef.getRoot()).getChildren().add(addedTextRef);}}

设置场景中的光标

sceneRef.cursorProperty().bind(choiceBoxRef.getSelectionModel().selectedItemProperty());

通过ID找到场景中的节点

textSceneH = new Text();textSceneH.getStyleClass().add("emphasized-text");textSceneH.setId("sceneHeightText");Hyperlink hyperlink = new Hyperlink("lookup");hyperlink.setOnAction((javafx.event.ActionEvent e) -> {System.out.println("sceneRef:" + sceneRef);Text textRef = (Text) sceneRef.lookup("#sceneHeightText");System.out.println(textRef.getText());});

场景引用中根据ID获取文本对象,并获取对象的内容。

从场景访问舞台

labelStageX.textProperty().bind(new SimpleStringProperty("Stage x: ").concat(sceneRef.getWindow().xProperty().asString()));labelStageY.textProperty().bind(new SimpleStringProperty("Stage y: ").concat(sceneRef.getWindow().yProperty().asString()));

向场景内容序列中插入节点

// Define an unmanaged node that will display TextText addedTextRef = new Text(0, -30, "");addedTextRef.setTextOrigin(VPos.TOP);addedTextRef.setFill(Color.BLUE);addedTextRef.setFont(Font.font("Sans Serif", FontWeight.BOLD, 16));addedTextRef.setManaged(false);// Bind the text of the added Text node to the fill property of the SceneaddedTextRef.textProperty().bind(new SimpleStringProperty("Scene fill: ").concat(sceneRef.fillProperty()));// Add the Text node to the FlowPane((FlowPane) sceneRef.getRoot()).getChildren().add(addedTextRef);

场景中用CSS来修饰节点

sceneRef.getStylesheets().add("onTheScene.css");...code omitted...// When the selected radio button changes, set the appropriate stylesheettoggleGrp.selectedToggleProperty().addListener((ov, oldValue, newValue) -> {String radioButtonText = ((RadioButton) toggleGrp.getSelectedToggle()).getText();sceneRef.getStylesheets().clear();sceneRef.getStylesheets().addAll("/"+radioButtonText);});

处理输入事件

查询鼠标、键盘、触摸和手势事件和处理程序理解键盘事件理解鼠标事件理解触摸事件理解手势事件

场景中的动画节点

package sample;/*** @author: Administrator* @date: /03/17 22:14* @description:*/import javafx.animation.Animation;import javafx.animation.Interpolator;import javafx.animation.KeyFrame;import javafx.animation.KeyValue;import javafx.animation.Timeline;import javafx.application.Application;import javafx.beans.property.DoubleProperty;import javafx.beans.property.SimpleDoubleProperty;import javafx.scene.Group;import javafx.scene.Scene;import javafx.scene.control.Button;import javafx.scene.layout.HBox;import javafx.scene.paint.Color;import javafx.scene.shape.Line;import javafx.stage.Stage;import javafx.util.Duration;public class Metronome1Main extends Application {DoubleProperty startXVal = new SimpleDoubleProperty(100.0);Button startButton;Button pauseButton;Button resumeButton;Button stopButton;Line line;Timeline anim;public static void main(String[] args) {Application.launch(args);}@Overridepublic void start(Stage stage) {anim = new Timeline(new KeyFrame(new Duration(0.0), new KeyValue(startXVal, 100.)),new KeyFrame(new Duration(1000.0), new KeyValue(startXVal, 300., Interpolator.LINEAR)));anim.setAutoReverse(true);anim.setCycleCount(Animation.INDEFINITE);line = new Line(0, 50, 200, 400);line.setStrokeWidth(4);line.setStroke(Color.BLUE);startButton = new Button("start");startButton.setOnAction(e -> anim.playFromStart());pauseButton = new Button("pause");pauseButton.setOnAction(e -> anim.pause());resumeButton = new Button("resume");resumeButton.setOnAction(e -> anim.play());stopButton = new Button("stop");stopButton.setOnAction(e -> anim.stop());HBox commands = new HBox(10,startButton,pauseButton,resumeButton,stopButton);commands.setLayoutX(60);commands.setLayoutY(420);Group group = new Group(line, commands);Scene scene = new Scene(group, 400, 500);line.startXProperty().bind(startXVal);startButton.disableProperty().bind(anim.statusProperty().isNotEqualTo(Animation.Status.STOPPED));pauseButton.disableProperty().bind(anim.statusProperty().isNotEqualTo(Animation.Status.RUNNING));resumeButton.disableProperty().bind(anim.statusProperty().isNotEqualTo(Animation.Status.PAUSED));stopButton.disableProperty().bind(anim.statusProperty().isEqualTo(Animation.Status.STOPPED));stage.setScene(scene);stage.setTitle("Metronome 1");stage.show();}}

为动画使用时间线

DoubleProperty startXVal = new SimpleDoubleProperty(100.0);...code omitted...Timeline anim = new Timeline(new KeyFrame(new Duration(0.0), new KeyValue(startXVal, 100.)),new KeyFrame(new Duration(1000.0), new KeyValue(startXVal, 300., Interpolator.LINEAR)));anim.setAutoReverse(true);anim.setCycleCount(Animation.INDEFINITE);...code omitted...line = new Line(0, 50, 200, 400);line.setStrokeWidth(4);line.setStroke(Color.BLUE);...code omitted...line.startXProperty().bind(startXVal);line = LineBuilder.create().startY(50).endX(200).endY(400).strokeWidth(4).stroke(Color.BLUE).build();

为时间线插入KeyFrame

Timeline实例包含两个KeyValue实例,在1s时间内,startXVal从100线性变化到300。将这个属性绑定到line对象的startProperty属性上即可让直线运动起来。

Timeline anim = new Timeline(new KeyFrame(new Duration(0.0), new KeyValue(startXVal, 100.)),new KeyFrame(new Duration(1000.0), new KeyValue(startXVal, 300., Interpolator.LINEAR)));

控制时间线

通过Timeline的playFromStart(),pause(),play(),stop()控制动画开始,暂停,播放,停止。

startButton = new Button("start");startButton.setOnAction(e -> anim.playFromStart());pauseButton = new Button("pause");pauseButton.setOnAction(e -> anim.pause());resumeButton = new Button("resume");resumeButton.setOnAction(e -> anim.play());stopButton = new Button("stop");stopButton.setOnAction(e -> anim.stop());

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。