• JavaFX的目录结构, 项目创建和发布, 基于JDK11+JavaFX SDK17


    JDK 和 JavaFX SDK

    需要使用JDK11, 推荐使用 https://adoptium.net/releases.html

    JDK11

    JavaFX 11 不再是JDK的一部分, 需要单独安装, 或者直接通过Maven Dependency引入.
    参考 https://stackoverflow.com/questions/52467561/intellij-cant-recognize-javafx-11-with-openjdk-11

    Start Guide: https://openjfx.io/openjfx-docs/#introduction

    • JavaFX 11 is not part of the JDK anymore
    • You can get it in different flavors, either as an SDK or as regular dependencies (maven/gradle).
    • You will need to include it to the module path of your project, even if your project is not modular.

    如果不使用Maven, 需要在 https://gluonhq.com/products/javafx/ 下载对应版本的sdk,

    JDK9之后的模块化

    https://www.oracle.com/corporate/features/understanding-java-9-modules.html

    不使用 Maven 创建 JavaFX 项目

    例子

    使用 Maven 创建JavaFX项目

    使用 Maven 创建 JavaFX 项目是较简单方便的一种方式, 不需要关心包依赖关系, 只需要手工初始化一个项目结构, 剩下的事都可以交给Maven处理.

    1. 项目结构

    项目结构如下, 其中resources目录下的资源文件, 可以放在 resources 根目录, 也可以放到resources/org/openjfx, 两者在App.java中的载入方式不同

    ├── javafx_test01
    │   ├── pom.xml
    │   ├── src
    │   │   └── main
    │   │       ├── java
    │   │       │   ├── com
    │   │       │   │   └── rockbb
    │   │       │   │       ├── App.java
    │   │       │   │       ├── PrimaryController.java
    │   │       │   │       └── SecondaryController.java
    │   │       │   └── module-info.java
    │   │       └── resources
    │   │           └── com
    │   │               └── rockbb
    │   │                   ├── primary.fxml
    │   │                   ├── secondary.fxml
    │   │                   └── styles.css
    └── settings.xml
    
    

    2. pom.xml

    指定JDK版本为11, javafx版本为17.0.1, javafx.maven.plugin使用最新的0.0.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/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.rockbb</groupId>
        <artifactId>javafx-test01</artifactId>
        <version>1.0-SNAPSHOT</version>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.release>11</maven.compiler.release>
            <javafx.version>17.0.1</javafx.version>
            <javafx.maven.plugin.version>0.0.8</javafx.maven.plugin.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-controls</artifactId>
                <version>${javafx.version}</version>
            </dependency>
            <dependency>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-fxml</artifactId>
                <version>${javafx.version}</version>
            </dependency>
        </dependencies>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.1</version>
                    <configuration>
                        <release>${maven.compiler.release}</release>
                        <source>${maven.compiler.release}</source>
                        <target>${maven.compiler.release}</target>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.openjfx</groupId>
                    <artifactId>javafx-maven-plugin</artifactId>
                    <version>${javafx.maven.plugin.version}</version>
                    <configuration>
                        <jlinkImageName>hellofx</jlinkImageName>
                        <launcher>launcher</launcher>
                        <mainClass>hellofx/org.openjfx.App</mainClass>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
    
    

    3. module-info.java

    这里定义项目模块的可见度, 反射的可见度, 以及依赖的其他模块. 后面的opens ... to 和 exports 需要使用自己工程的包名

    module hellofx {
        requires javafx.controls;
        requires javafx.fxml;
    
        opens com.rockbb to javafx.fxml;
        exports com.rockbb;
    }
    

    4. App.java

    这是应用的入口. 下面的载入方式对应资源文件在根目录, 如果要按 package 放, 去掉其中的.getClassLoader()就可以了

    package com.rockbb;
    
    import javafx.application.Application;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.stage.Stage;
    
    import java.io.IOException;
    
    
    public class App extends Application {
    
        private static Scene scene;
    
        @Override
        public void start(Stage stage) throws IOException {
            scene = new Scene(loadFXML("primary"));
            scene.getStylesheets().add(getClass().getResource("styles.css").toExternalForm());
            stage.setScene(scene);
            stage.show();
        }
    
        static void setRoot(String fxml) throws IOException {
            scene.setRoot(loadFXML(fxml));
        }
    
        private static Parent loadFXML(String fxml) throws IOException {
            FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource(fxml + ".fxml"));
            return fxmlLoader.load();
        }
    
        public static void main(String[] args) {
            launch();
        }
    
    }
    

    5. PrimaryController.java

    package com.rockbb;
    
    import java.io.IOException;
    import javafx.fxml.FXML;
    import javafx.scene.control.Button;
    
    public class PrimaryController {
    
        public Button primaryButton;
    
        @FXML
        private void switchToSecondary() throws IOException {
            App.setRoot("secondary");
        }
    }
    

    6. SecondaryController.java

    package com.rockbb;
    
    import java.io.IOException;
    import javafx.fxml.FXML;
    import javafx.scene.control.Button;
    
    public class SecondaryController {
    
        public Button secondaryButton;
    
        @FXML
        private void switchToPrimary() throws IOException {
            App.setRoot("primary");
        }
    }
    

    7. primary.fxml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.scene.layout.VBox?>
    <?import javafx.scene.control.Label?>
    <?import javafx.scene.control.Button?>
    <?import javafx.geometry.Insets?>
    
    <VBox alignment="CENTER" spacing="20.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1"
          fx:controller="com.rockbb.PrimaryController">
       <padding>
          <Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/>
       </padding>
       <Label text="Primary View"/>
       <Button fx:id="primaryButton" text="Switch to Secondary View" onAction="#switchToSecondary"/>
    </VBox>
    

    8. secondary.fxml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.scene.layout.VBox?>
    <?import javafx.scene.control.Label?>
    <?import javafx.scene.control.Button?>
    <?import javafx.geometry.Insets?>
    
    <VBox alignment="CENTER" spacing="20.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1"
          fx:controller="com.rockbb.SecondaryController">
        <padding>
            <Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/>
        </padding>
        <Label text="Secondary View"/>
        <Button fx:id="secondaryButton" text="Switch to Primary View" onAction="#switchToPrimary"/>
    </VBox>
    

    8. styles.css

    .button {
        -fx-text-fill: blue;
    }
    

    运行

    IDEA中在App类上右键菜单, 点Run即可运行

    打包发布

    在JDK16之前, 可以使用jlink将项目打包为带目录结构的可执行文件, 在pom中修改javafx-maven-plugin的配置

        <build>
            <plugins>
                ...
                <plugin>
                    <groupId>org.openjfx</groupId>
                    <artifactId>javafx-maven-plugin</artifactId>
                    <version>${javafx.maven.plugin.version}</version>
                    <configuration>
                        <!-- 指定jlink路径,如果你的系统中默认路径是其他版本的jdk, 就必须用这个参数指定 -->
                        <jlinkExecutable>/opt/jdk/jdk-11.0.12/bin/jlink</jlinkExecutable>
                        <!-- 压缩比例, 值可以为0,1,2, 默认为0 -->
                        <compress>2</compress>
                        <!-- Remove the includes directory in the resulting runtime image -->
                        <noHeaderFiles>true</noHeaderFiles>
                        <!-- Strips debug information out -->
                        <stripDebug>true</stripDebug>
                        <!-- Remove the man directory in the resulting Java runtime image -->
                        <noManPages>true</noManPages>
                        <!-- Add a launcher script -->
                        <launcher>launcher</launcher>
                        <!-- what main needs to be launched by specifying module, package and class -->
                        <mainClass>hellofx/com.rockbb.App</mainClass>
                        <!-- The name of the folder with the resulting runtime image -->
                        <jlinkImageName>hellofx</jlinkImageName>
                        <!-- When set, creates a zip of the resulting runtime image -->
                        <jlinkZipName>hellofx</jlinkZipName>
                    </configuration>
                </plugin>
                ...
            </plugins>
        </build>
    

    执行打包

    clean compile javafx:jlink -f pom.xml
    

    压缩使用2时, 最终产生的lib/modules尺寸会明显小很多, 这个并不一定体现到zip包的大小上, 2产生的zip包可能比0更大

    在JDK16之后, 可以使用jpackage.

    参考

  • 相关阅读:
    我的利器
    老树新芽——矩估计遇到神经网络
    QuantLib 金融计算——数学工具之随机数发生器
    《Implementing QuantLib》译后记
    c# 大批量用户访问数据库报错
    阿里云redis映射到阿里云服务器
    C# 输出字符串到文本文件中
    SQL Server 怎么在分页获取数据的同时获取到总记录数
    C# 当前 .NET SDK 不支持将 .NET Core 2.1 设置为目标。请将 .NET Core 2.0 或更低版本设置为目标,或使用支持 .NET Core 2.1 的 .NET SDK 版本。
    c# 项目之间循环引用vs弹窗提醒
  • 原文地址:https://www.cnblogs.com/milton/p/15456546.html
Copyright © 2020-2023  润新知