javafx

news2024/11/19 15:23:52

JavaFX

JavaFX简介

JavaFX是一个用于创建富客户端应用程序的图形用户界面(GUI)框架。它是Java平台的一部分,从Java 8开始成为Java的标准库。

JavaFX提供了丰富的图形和多媒体功能,使开发人员能够创建具有吸引力和交互性的应用程序。它支持各种UI控件、布局和样式,以及动画、图形渲染和多媒体处理等功能。

以下是一些JavaFX的主要特点和功能:

  1. UI控件:JavaFX提供了一系列内置的UI控件,如按钮、标签、文本框、列表、表格等,以及自定义控件的能力。

  2. 布局:JavaFX支持多种布局管理器,如栈布局(StackPane)、流布局(FlowPane)、网格布局(GridPane)等,以便开发人员可以轻松地设计和排列应用程序的界面。

  3. 样式和主题:JavaFX使用CSS来定义应用程序的样式和外观。开发人员可以通过CSS样式表来自定义控件的外观,从而实现更好的界面设计。

  4. 动画和过渡效果:JavaFX提供了强大的动画和过渡效果支持,可以实现平滑的界面过渡、元素的渐变、旋转、缩放等效果,增强用户体验。

  5. 多媒体支持:JavaFX支持音频和视频播放、图像处理和渲染等多媒体功能,可以创建具有丰富多媒体内容的应用程序。

  6. 事件处理:JavaFX提供了事件模型和事件处理机制,开发人员可以通过监听和处理事件来实现应用程序的交互性。

  7. 场景图和渲染引擎:JavaFX使用场景图(scene graph)作为UI的基础结构,通过渲染引擎将场景图渲染到屏幕上。

JavaFX可以与Java语言无缝集成,可以使用Java代码或FXML(一种基于XML的语言)来创建界面。它还提供了丰富的API和工具,以支持开发人员构建跨平台的富客户端应用程序。

需要注意的是,从Java 11开始,JavaFX不再是Java标准库的一部分,而是作为一个独立的模块进行开发和发布。因此,如果您使用的是Java 11及更高版本,您需要单独下载和安装JavaFX,并将其添加到您的项目中。

Maven JavaFX 项目

new Project

mvn project

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.lihaozhe</groupId>
    <artifactId>demo01</artifactId>
    <version>1.0.0</version>
    <description>JavaFX mvn project</description>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <junit.version>5.10.0</junit.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>17.0.8</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>17.0.8</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-graphics</artifactId>
            <version>17.0.8</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.8</version>
                <executions>
                    <execution>
                        <!-- Default configuration for running with: mvn clean javafx:run -->
                        <id>default-cli</id>
                        <configuration>
                            <!-- 主窗口启动类为 com.lihaozhe.App -->
                            <mainClass>com.lihaozhe.App</mainClass>
                            <launcher>app</launcher>
                            <jlinkZipName>app</jlinkZipName>
                            <jlinkImageName>app</jlinkImageName>
                            <noManPages>true</noManPages>
                            <stripDebug>true</stripDebug>
                            <noHeaderFiles>true</noHeaderFiles>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

JavaFX程序基本机构

主窗口启动类

com.lihaozhe.App01

package com.lihaozhe;

import javafx.application.Application;
import javafx.stage.Stage;

/**
 * @author 李昊哲
 * @version 1.0
 * @Description 主敞口启动类
 * @create 2023/9/3
 */
public class App01 extends Application {
    /**
     * @param stage 主窗口
     * @throws Exception IO异常
     */
    @Override
    public void start(Stage stage) throws Exception {
        // 设置主窗口标题
        stage.setTitle("我爱你中国");
        // 显示窗口
        stage.show();
    }


    public static void main(String[] args) {
        // 父类中继承过来的静态方法启动 launch 方法会自动调用 start 方法
        launch(args);
    }
}

注意,此时直接启动会出现如下报错:

错误: 缺少 JavaFX 运行时组件, 需要使用该组件来运行此应用程序

导入JavaFX模块

从Java 11开始,JavaFX不再是Java标准库的一部分,而是作为一个独立的模块进行开发和发布。

因此,如果您使用的是Java 11及更高版本,您需要单独下载和安装JavaFX,并将其添加到您的项目中

src/main/java/module-info.java

module com.lihaozhe {
    requires javafx.controls;
    requires javafx.fxml;


    opens com.lihaozhe to javafx.fxml;
    exports com.lihaozhe;
}

module-info.java

运行主窗口类

JavaFX

JavaFX基本结构

package com.lihaozhe;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

/**
 * @author 李昊哲
 * @version 1.0
 * @Description 主敞口启动类
 * @create 2023/9/3
 */
public class App01 extends Application {
    /**
     * @param stage 主窗口
     * @throws Exception IO异常
     */
    @Override
    public void start(Stage stage) throws Exception {
        // 设置主窗口标题
        stage.setTitle("我爱你中国");
        // Label 标签
        Label label = new Label("我爱你中国,亲爱的母亲!");
        // BorderPane 边框布局 将编写好的标签 放在边框布局中 默认标签居中显示
        // 常见的布局如下:
        // BorderPane、StackPane、GridPane、FlowPane、SplitPane、TabPane、AnchorPane
        // BorderPane 提供了5个放置节点的区域:top, bottom, left, right, 和 center
        // HBox 横的一个一个摆
        // VBox 竖的一个一个摆
        // StackPane 新放的东西会覆盖原来的东西
        // GridPane 一格一格的放,可以设置行和列
        // FlowPane 会一行一行的摆,放不下就拐到下一行
        // SplitPane 能用鼠标拖动的面板
        // Accordion 可以翻的页面
        // TabPane 一个一个的标签
        // AnchorPane我们可以看到,每个页面里面都有AnchorPane,
        // 意思就跟随外面的移动,外面的往左,里面的就往左,外面的往右,里面的就往右
        BorderPane borderPane = new BorderPane(label);
        // Scene 场景 将编写好的布局 放在场景中
        Scene scene = new Scene(borderPane, 600, 600);
        // 将场景放在主窗口内
        stage.setScene(scene);
        // 显示窗口
        stage.show();
    }


    public static void main(String[] args) {
        // 父类中继承过来的静态方法启动 launch 方法会自动调用 start 方法
        launch(args);
    }
}

javafx 自定义场景

package com.lihaozhe;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

/**
 * @author 李昊哲
 * @version 1.0
 * @Description 主敞口启动类
 * @create 2023/9/3
 */
public class App02 extends Application {
    /**
     * @param stage 主窗口
     * @throws Exception IO异常
     */
    @Override
    public void start(Stage stage) throws Exception {
        // 设置主窗口标题
        stage.setTitle("我爱你中国");
        // Button 按钮
        Button button = new Button("你过来呀");
        // 按钮点击事件
        button.setOnAction(event -> {
            // 通过系统默认浏览器打开指定的网页
            getHostServices().showDocument("https://blog.csdn.net/qq_24330181");
            getHostServices().showDocument("https://space.bilibili.com/480308139");
        });
        // BorderPane 边框布局 将编写好的标签 放在边框布局中 默认标签居中显示
        // 常见的布局如下:
        // BorderPane、StackPane、GridPane、FlowPane、SplitPane、TabPane、AnchorPane
        // BorderPane 提供了5个放置节点的区域:top, bottom, left, right, 和 center
        // HBox 横的一个一个摆
        // VBox 竖的一个一个摆
        // StackPane 新放的东西会覆盖原来的东西
        // GridPane 一格一格的放,可以设置行和列
        // FlowPane 会一行一行的摆,放不下就拐到下一行
        // SplitPane 能用鼠标拖动的面板
        // Accordion 可以翻的页面
        // TabPane 一个一个的标签
        // AnchorPane我们可以看到,每个页面里面都有AnchorPane,
        // 意思就跟随外面的移动,外面的往左,里面的就往左,外面的往右,里面的就往右
        BorderPane borderPane = new BorderPane(button);
        // Scene 场景 将编写好的布局 放在场景中
        Scene scene = new Scene(borderPane, 600, 600);
        // 将场景放在主窗口内
        stage.setScene(scene);
        // 显示窗口
        stage.show();
    }


    public static void main(String[] args) {
        // 父类中继承过来的静态方法启动 launch 方法会自动调用 start 方法
        launch(args);
    }
}

BorderPane、StackPane、GridPane、FlowPane、SplitPane、TabPane、AnchorPane

Application简介

要创建JavaFX应用程序,您需要遵循以下步骤:

  1. 设置开发环境:安装Java开发工具包(JDK)和支持JavaFX开发的集成开发环境(IDE),如Eclipse、IntelliJ IDEA或NetBeans。

  2. 创建一个新的JavaFX项目:打开您的IDE并创建新的JavaFXProject。这将建立必要的项目结构和依赖关系。

  3. 创建主应用程序类:在项目内部,创建一个扩展javafx.application.application类的新类。这个类将作为JavaFX应用程序的入口点。

  4. 重写start方法:在您的主应用程序类中,重写start方法。此方法用于定义应用程序的初始UI布局和行为。

  5. 创建主阶段(primary stage)和场景(scene):在start方法中,创建一个新的javafx.stage.stage对象,该对象表示应用程序的主窗口。然后,创建一个javafx.scene.scene对象,并将其设置为舞台的场景。

  6. 设计UI:在场景内部,您可以使用JavaFX的内置UI控件或通过创建自定义控件来添加各种UI控件和元素。可以使用不同的布局管理器来排列场景中的控件。

  7. 添加事件处理:实现事件处理程序来处理用户与UI控件的交互。您可以使用setOnAction方法或其他适当的方法将事件处理程序附加到控件。

  8. 启动应用程序:在您的主方法或单独的启动器类中,调用application.slaunch方法来启动JavaFX应用程序。这将调用主应用程序类的start方法。

  9. 构建并运行应用程序:构建您的项目并运行该应用程序。您应该看到JavaFX应用程序窗口,其中包含已定义的UI和行为。

以下是一个显示Hello,JavaFX!标签的JavaFX应用程序的简单示例:

package com.lihaozhe;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

/**
 * @author 李昊哲
 * @version 1.0
 * @Description
 * @create 2023/9/3
 */
public class HelloWorldApp extends Application {

    @Override
    public void start(Stage primaryStage) {
        Label label = new Label("Hello, JavaFX!");

        StackPane root = new StackPane();
        root.getChildren().add(label);

        Scene scene = new Scene(root, 300, 200);

        primaryStage.setTitle("Hello World");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

这是一个基本示例,但您可以通过添加更多的UI控件、事件处理和其他功能来扩展它,以创建更复杂的JavaFX应用程序。

Stage

在JavaFX中,stage 表示JavaFX应用程序中的顶级窗口。它是javafx.stage.stage类的一个实例,用作一个或多个场景的容器。

要在JavaFX中创建和使用阶段,请执行以下步骤:

  1. 创建一个stage对象:您可以使用javafx.stage.stage类创建一个新的stage对象。通常,您在javafx.application.application子类的 start() 方法中创建一个stage对象。

  2. 设置场景:要在舞台内部显示内容,需要设置场景。场景表示将在舞台内显示的内容。使用舞台对象的 setScene()方法设置场景。

  3. .设置标题:您可以使用setTitle()方法为舞台设置标题。标题将显示在窗口的标题栏中。

  4. 设置其他属性:您可以设置后台文件的各种属性,如大小、可调整大小的行为和可见性。使用“Stage”类提供的适当方法,如setWidth(), setHeight(), setResizable()show()

  5. 处理阶段事件:您可以注册事件处理程序来处理与阶段相关的事件,例如当它显示、隐藏或关闭时。使用setOn...() 方法,如setOnShown()setOnHidden()setOnCloseRequest(),将事件处理程序附加到阶段。

    以下是一个示例,演示如何在JavaFX中创建和使用阶段:

package com.lihaozhe;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

import java.util.Optional;

/**
 * @author 李昊哲
 * @version 1.0
 * @Description
 * @create 2023/9/3
 */
public class StageExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        // Button 按钮
        Button button = new Button("你过来呀");
        BorderPane root = new BorderPane(button);
        // Create a scene with the root node
        Scene scene = new Scene(root, 400, 300);

        // Set the scene for the stage
        primaryStage.setScene(scene);

        // Set the title of the stage
        primaryStage.setTitle("JavaFX Stage Example");

        // width,height,用于设置窗口大小
        primaryStage.setWidth(800);
        primaryStage.setHeight(600);

        // resizable,是否允许改变窗口大小
        primaryStage.setResizable(true);

        // x,y,用于设置窗口在桌面上显示的位置
        primaryStage.setX(100);
        primaryStage.setY(100);

        // 用户设置窗口的样式
        // 我们可以通过枚举类选择窗口样式,默认的窗口样式为“DECORATED”
        // 枚举类StageStyle有以下样式:
        // DECORATED 用纯白背景和平台装饰定义一个普通的窗口样式
        // UNDECORATED 定义一个窗口样式,背景为纯白,没有任何装饰
        //  当我们没有为Stage设置Sence时,我们在桌面上将看不到任何东西
        //  当我们有为Stage设置Sence时,可以看到,该窗口样式的最大特点就是,我们看不到标题、图表、隐藏按钮,全屏按钮、关闭按钮那一栏
        // TRANSPARENT 定义具有透明背景且没有装饰的窗口样式
        // UTILITY 定义具有纯白背景和用于实用程序窗口的最小平台装饰的样式
        // UNIFIED 使用平台装饰定义窗口样式,并消除客户端区域和装饰之间的边界。客户区背景与装修统一
        primaryStage.initStyle(StageStyle.DECORATED);

        // primaryStage.initModality(Modality.WINDOW_MODAL);
        // 设置窗口的图标
        // primaryStage.getIcons().add(new Image("https://img1.baidu.com/it/u=2865456449,2930074044&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500"));
        // primaryStage.getIcons().add(new Image("file:///D:\\dev\\java\\code\\javafx\\demo01\\src\\main\\resources\\icon\\java02.png"));
        // 获取图标文件类路径
        String path = this.getClass().getResource("/icon/java02.png").getPath();
        // 设置协议
        String protocol = "file://";
        primaryStage.getIcons().add(new Image(protocol + path));

        // 按钮点击事件
        button.setOnAction(event -> {
            Stage stage = new Stage();
            stage.setTitle("自强不息");
            stage.setWidth(400);
            stage.setHeight(300);

            // 将主窗口设置为父窗口
            stage.initOwner(primaryStage);
            // Modality 模态框
            // NONE
            // WINDOW_MODAL 需要父窗口 只有父窗口不可用其它窗口可用
            // APPLICATION_MODAL 应用模态 只有本窗口可用其它窗口不可用
            stage.initModality(Modality.WINDOW_MODAL);
            stage.show();
        });

        // Show the stage
        primaryStage.show();


        // 取消系统默认退出
        Platform.setImplicitExit(false);
        // Register an event handler for the close request event
        primaryStage.setOnCloseRequest(event -> {
            System.out.println("Closing the stage...");
            // 取消系统默认关闭窗口
            event.consume();
            Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
            alert.setTitle("退出程序");
            alert.setHeaderText(null);
            alert.setContentText("是否退出程序");
            Optional<ButtonType> result = alert.showAndWait();
            if (result.get() == ButtonType.OK) {
                // 关闭窗口
                primaryStage.close();
                // 退出程序
                Platform.exit();
            }
        });
    }

    public static void main(String[] args) {
        launch(args);
    }
}

在本例中,我们使用 stage 类创建一个舞台对象,并设置一个带有标签的场景作为舞台的内容。我们设置了舞台的标题、大小和可调整大小的行为。最后,我们展示阶段并为关闭请求事件注册一个事件处理程序。

您可以通过设置舞台图标、应用CSS样式或添加动画和效果来进一步自定义舞台。

Secne

在JavaFX中,Secne 表示显示在JavaFX应用程序的窗口(阶段)内的内容。它充当组成应用程序用户界面的所有视觉元素(节点)的容器。

要在JavaFX中创建场景,需要执行以下步骤:

  1. 创建根节点:根节点是作为场景中所有其他节点的父节点的顶级节点。它可以是javafx.scene.Parent类的任何子类,如javafx.secene.layout.Panejavafx-secene.layout.GridPane。您可以将子节点添加到根节点以定义场景的布局和结构。

  2. 创建场景对象:使用javafx.scene.scene类创建新的场景对象。将根节点以及所需的场景宽度和高度作为参数传递给构造函数。

  3. 为 Stage 设置场景:要在窗口中显示场景,需要将其设置为javafx.stage.stage对象的场景。该阶段代表JavaFX的主窗口

  4. 显示stage:最后,调用stage对象上的 Show() 方法使其可见。这将在窗口内显示场景及其内容。

下面是一个示例,演示如何创建一个带有标签的简单JavaFX场景:

package com.lihaozhe;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

/**
 * @author 李昊哲
 * @version 1.0
 * @Description
 * @create 2023/9/3
 */
public class SceneExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        // 设置主窗口标题
        primaryStage.setTitle("我爱你中国");

        Button button0 = new Button("进入场景1");
        Button button1 = new Button("进入场景0");

        BorderPane borderPane0 = new BorderPane(button0);
        BorderPane borderPane1 = new BorderPane(button1);

        int width = 800;
        int height = 600;
        Scene scene0 = new Scene(borderPane0, width, height);
        Scene scene1 = new Scene(borderPane1, width, height);

        // 将场景放在主窗口内
        primaryStage.setScene(scene0);

        // 显示窗口
        primaryStage.show();
        button0.setOnAction(event -> primaryStage.setScene(scene1));
        button1.setOnAction(event -> primaryStage.setScene(scene0));
    }

    public static void main(String[] args) {
        launch(args);
    }
}

在本例中,我们创建一个 StackPane 作为根节点,并向其添加一个 Label 。然后,我们使用根节点创建一个场景,并将其设置为舞台的场景。最后,我们设置了舞台的标题并展示出来。

您可以通过设置场景的背景颜色、添加CSS样式或将动画和效果应用于场景中的节点来进一步自定义场景。

Node通用UI属性

package com.lihaozhe;

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

/**
 * @author 李昊哲
 * @version 1.0
 * @Description
 * @create 2023/9/3
 */
public class NodeExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        Label label = new Label("Hello, JavaFX!");

        // 样式
        StringBuilder style = new StringBuilder();
        style.append("-fx-background-color: #FF0000;");
        style.append("-fx-border-color: #00FF00;");
        style.append("-fx-border-image-width: 3px;");
        label.setStyle(style.toString());

        // 宽度
        label.setPrefWidth(100);
        // 高度
        label.setPrefHeight(50);

        // 透明度 取值范围 0 到 1
        label.setOpacity(0.5);

        // 角度
        label.setRotate(30);

        // 内容居中显示
        label.setAlignment(Pos.CENTER);

        // 平移
        label.setTranslateX(50);
        label.setTranslateY(50);

        // 位置
        label.setLayoutX(50);
        label.setLayoutY(50);

        AnchorPane root = new AnchorPane();
        root.getChildren().add(label);

        Scene scene = new Scene(root, 300, 200);

        primaryStage.setTitle("Hello World");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

属性绑定与监听

package com.lihaozhe;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

/**
 * @author 李昊哲
 * @version 1.0
 * @Description
 * @create 2023/9/3
 */
public class PropertyExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        // 圆形 属性
        Circle circle = new Circle();

        circle.setCenterX(400);
        circle.setCenterY(300);
        circle.setRadius(100);
        circle.setStroke(Color.BLACK);
        circle.setFill(Color.WHITE);
        AnchorPane root = new AnchorPane();
        root.getChildren().add(circle);

        Scene scene = new Scene(root, 800, 600);
        // 圆心始终问宽度和高度一半的位置
        circle.centerXProperty().bind(scene.widthProperty().divide(2));
        circle.centerYProperty().bind(scene.heightProperty().divide(2));

        // 属性监听
        // observable 监听对象
        // oldValue 旧值
        // newValue 新值
        circle.centerXProperty().addListener((observable, oldValue, newValue) -> System.out.println(observable + "\t" + oldValue + "\t" + newValue));

        primaryStage.setTitle("Hello World");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

图片

package com.lihaozhe;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;


/**
 * @author 李昊哲
 * @version 1.0
 * @Description
 * @create 2023/9/3
 */
public class ImageExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        // 获取图片文件类路径
        String path = this.getClass().getResource("/icon/java02.png").getPath();
        // 设置协议
        String protocol = "file://";
        Image image = new Image(protocol + path);
        ImageView imageView = new ImageView(image);
        BorderPane root = new BorderPane(imageView);
        Scene scene = new Scene(root, 800, 600);

        primaryStage.setTitle("Hello World");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

事件驱动

package com.lihaozhe;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;


/**
 * @author 李昊哲
 * @version 1.0
 * @Description
 * @create 2023/9/3
 */
public class EventExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        // 获取图片文件类路径
        String path = this.getClass().getResource("/icon/dog.png").getPath();
        // 设置协议
        String protocol = "file://";
        Image image = new Image(protocol + path);
        ImageView imageView = new ImageView(image);
        imageView.setFitWidth(100);
        imageView.setFitHeight(100);
        imageView.setRotate(90);
        AnchorPane root = new AnchorPane(imageView);
        Scene scene = new Scene(root, 800, 600);

        primaryStage.setTitle("Hello World");


        // 键盘抬起
        scene.setOnKeyReleased(event -> {
            // 获取键盘事件码
            switch (event.getCode()) {
                case UP -> {
                    imageView.setRotate(0);
                    imageView.setLayoutY(imageView.getLayoutY() - 10);
                }
                case RIGHT -> {
                    imageView.setRotate(90);
                    imageView.setLayoutX(imageView.getLayoutX() + 10);
                }
                case DOWN -> {
                    imageView.setRotate(180);
                    imageView.setLayoutY(imageView.getLayoutY() + 10);
                }
                case LEFT -> {
                    imageView.setRotate(270);
                    imageView.setLayoutX(imageView.getLayoutX() - 10);
                }
            }
        });
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

FXML布局

FXML是一种以XML的格式表示JavaFX界面对象的文件,

FXML文件中的每一个元素可以映射到JavaFX中的一个类,

每个FXML元素的属性或者其子元素都可以映射为该对应JavaFXML类的属性.

package com.lihaozhe.fxml;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

public class FxmlApplication extends Application {
    @Override
    public void start(Stage stage) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(FxmlApplication.class.getResource("fxml-view.fxml"));
        Scene scene = new Scene(fxmlLoader.load(), 640, 480);
        stage.setTitle("Hello!");
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}

package com.lihaozhe.fxml;

import javafx.fxml.FXML;
import javafx.scene.control.Label;
/**
 * 用来绑定这个fxml文件用的,用于控制这个界面的一些操作,实现一些功能
 */
public class FxmlController {
    @FXML
    private Label welcomeText;

    @FXML
    protected void onHelloButtonClick() {
        welcomeText.setText("Welcome to JavaFX Application!");
    }
}

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>

<?import javafx.scene.control.Button?>
<VBox alignment="CENTER" spacing="20.0" xmlns:fx="http://javafx.com/fxml"
      fx:controller="com.lihaozhe.fxml.FxmlController">
  <padding>
    <Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/>
  </padding>

  <Label fx:id="welcomeText"/>
  <Button text="Hello!" onAction="#onHelloButtonClick"/>
</VBox>

javafx

javafx

javafx

Scene Builder

Scene Builder

官网:https://openjfx.io/

中文官网:https://openjfx.cn/

Scene Builder
Scene Builder
Scene Builder
Scene Builder
Scene Builder

IDEA整合Scene Builder

javafx

javafx
javafx
javafx
Scene Builder
Scene Builder

新建 JavaFX 项目

javafx
javafx
javafx
javafx

Scene Builder
Scene Builder

initialize

controller中的initialize方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1351663.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Proteus仿真】【Arduino单片机】数控稳压可调电源设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真Arduino单片机控制器&#xff0c;使用动态数码管、按键、PCF8591 AD/DAC、LM358放大电路模块等。 主要功能&#xff1a; 系统运行后&#xff0c;系统默认输出直流5V&#xff0c;数…

C#使用 OpenHardwareMonitor获取CPU或显卡温度、使用率、时钟频率相关方式

C# 去获取电脑相关的基础信息&#xff0c;还是需要借助 外部的库&#xff0c;我这边尝试了自己去实现它 网上有一些信息&#xff0c;但不太完整&#xff0c;都比较零碎&#xff0c;这边尽量将代码完整的去展示出来 OpenHardwareMonitor获取CPU的温度和频率需要管理员权限 在没…

第十二章 需求工程之一图胜千言

需求建模 可视化需求模型能帮助我们识别被遗漏的、不相关的和不一致的需求。数据流图&#xff08;DFD&#xff09;流程图&#xff0c;如泳道图状态转换图&#xff08;STD&#xff09;和状态表对话图决策表和决策树事件-响应表需求树用例图活动图实体关系图&#xff08;ERD&…

Win10升级到Win11

Win10升级到Win11 1. 下载PC健康状况检查应用2. 下载Win111. Windows 11 安装助手2. 创建Windows 11 安装3. 下载Windows 11 磁盘映像&#xff08;ISO&#xff09; 3. Windows 11 安装助手4. 安装成功 有些小伙伴的诉求是想使用一下当前最火的Win11操作系统怎么样。 这里就来安…

Java基础进阶(学习笔记)

注&#xff1a;本篇的代码和PPT图片来源于黑马程序员&#xff0c;本篇仅为学习笔记 static static 是静态的意思&#xff0c;可以修饰成员变量&#xff0c;也可以修饰成员方法 修饰成员的特点&#xff1a; 被其修饰的成员, 被该类的所有对象所共享 多了一种调用方式, 可以通过…

引导过程与服务控制

一、开机启动的完整过程 bios加电自检测-------mbr------grub----------加载内核文件------------启动第一个进程 简述&#xff1a;加电后bios程序会自检硬件&#xff0c;硬件无故障&#xff0c;会根据第一启动项去找内核&#xff0c;一般来说&#xff0c;第一启动项是硬盘&a…

初学者快速入门学习日语,PDF文档音频教学资料合集

一、资料描述 本套学习资料是很全面的&#xff0c;共有734份文件&#xff0c;包括PDF&#xff0c;PPT&#xff0c;表格&#xff0c;图片&#xff0c;音频等多种格式&#xff0c;可以作为初级日语的学习教材&#xff0c;也是非常适合初学者入门的&#xff0c;可以帮助大家快速的…

基本算法——深度优先搜索(DFS)和广度优先搜索(BFS)

深度优先搜索和广度优先搜索&#xff0c;都是图形搜索算法&#xff0c;它两相似&#xff0c;又却不同&#xff0c;在应用上也被用到不同的地方。这里拿一起讨论&#xff0c;方便比较。 一、深度优先搜索 深度优先搜索属于图算法的一种&#xff0c;是一个针对图和树的遍历算法&…

西城微科|充气泵方案PCBA和芯片

智能充气泵是一种常见的充气工具&#xff0c;它在我们的日常生活中扮演着重要的角色。它主要用于给车辆、自行车、橡皮艇、游泳圈等充气&#xff0c;方便人们在各种场合使用。它简单方便的操作&#xff0c;快速高效的充气速度&#xff0c;以及便携的设计&#xff0c;让我们能够…

ubuntu系统没有网络图标的解决办法

参考文章:https://blog.csdn.net/qq_56922632/article/details/132309643 1. 执行关闭网络服务的命令&#xff0c;关闭网络服务sudo service NetworkManager stop2. 删除网络的状态文件sudo rm /var/lib/NetworkManager/NetworkManager.state3. 修改网络的配置文件sudo vi /etc…

如何避免LLM的“幻觉”(Hallucination)

生成式大语言模型&#xff08;LLM&#xff09;可以针对各种用户的 prompt 生成高度流畅的回复。然而&#xff0c;大模型倾向于产生幻觉或做出非事实陈述&#xff0c;这可能会损害用户的信任。 大语言模型的长而详细的输出看起来很有说服力&#xff0c;但是这些输出很有可能是虚…

Modbus 通信协议 二

Modbus 常用缩写 通用Modbus帧结构 -应用数据单元&#xff08;ADU&#xff09; Modbus数据模型 Modbus ADU 和 PDU 的长度 Modbus PDU结构 串行链路上的 Modbus 帧结构 Modbus 地址规则 ASCLL 模式 和 RTU 模式的比较 RTU 模式 RTU 模式位序列 帧格式 帧的标识与鉴别 CRC 循环冗…

linux系统下sql脚本的执行与导出

terminal中执行 执行 mysql -u [username] -p -D [databasename] < [XXX.sql] 导出 mysql -u [username] -p [datbasename] > [XXX.sql] 导出的数据库名自定义。 mysql -u [username] -p [databasename] [tablename] > [xxx.sql] 导出表名自定义 mysql shell 执行 …

众和策略:沪指震荡跌0.21%,煤炭、电力等板块拉升,核电概念活跃

2日早盘&#xff0c;三大股指盘中震荡走低&#xff0c;创业板指跌逾1%&#xff0c;北证50指数逆市拉升&#xff1b;北向资金大幅流出。 到午间收盘&#xff0c;沪指跌0.21%报2968.7点&#xff0c;深成指跌0.91%&#xff0c;创业板指跌1.38%&#xff0c;北证50指数涨1.33%&…

Java学习路线第六篇:互联网生态(1)

这篇则分享Java学习路线第六part&#xff1a;互联网生态 恭喜你已经成功追到第六章节啦&#xff0c;要被自己的努力感动到了吧&#xff0c;而这节将承担起学完互联网生态的使命&#xff0c;本使命为单向契约&#xff0c;你可选择YES或者选择YES。 Linux Linux从入门到精通视…

基于电商场景的高并发RocketMQ实战-促销活动推送至用户完整流程、Spring结合RocketMQ的生产者消费者使用

&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308; 欢迎关注公众号&#xff08;通过文章导读关注&#xff09;&#xff0c;发送【资料】可领取 深入理解 Redis 系列文章结合电商场景讲解 Redis 使用场景、中间件系列…

【Apache-2.0】springboot-openai-chatgpt超级AI大脑产品架构图

springboot-openai-chatgpt: 一个基于SpringCloud的Chatgpt机器人&#xff0c;已对接GPT-3.5、GPT-4.0、百度文心一言、stable diffusion AI绘图、Midjourney绘图。用户可以在界面上与聊天机器人进行对话&#xff0c;聊天机器人会根据用户的输入自动生成回复。同时也支持画图&a…

【微服务架构】Spring Cloud入门概念讲解

目录 一、单体架构VS微服务架构 1.1 单体应用 单体架构的优点 单体应用的缺点 1.2 微服务“定义” 微服务的特性 微服务的缺点 微服务的适用场景 二、微服务常见概念与核心模块 三、Spring Cloud 工作流程 一、单体架构VS微服务架构 1.1 单体应用 一个归档包&#x…

数据损毁!250 亿美金的 Pinterest,在数据库选型上的翻车经历

原文链接 Pinterest 是一个以图片为主的社交网络&#xff0c;用户可以将图片保存或 "钉 / pin" 在自己的图板上。Pinterest 在 2019 年上市&#xff0c;目前市值 250 亿美金。本文内容主要根据 2012 年 Scaling Pinterest 的分享。 2012 年 1 月&#xff0c;Pinteres…

ARM NEON 指令

NEON指令 按照操作数类型可以分为正常指令、宽指令、窄指令、饱和指令、长指令。 正常指令&#xff1a;生成大小相同且类型通常与操作数向量相同到结果向量。长指令&#xff1a;对双字向量操作数执行运算&#xff0c;生产四字向量到结果。所生成的元素一般是操作数元素宽度到…