使用 Java Swing 和集成的 JavaFX 通过 Maven 创建可运行的 .jar - 实例化 JFXPanel 时应用程序崩溃 [英] Creating a runnable .jar with Maven using Java Swing and integrated JavaFX - App crashes when JFXPanel is being instantiated

查看:19
本文介绍了使用 Java Swing 和集成的 JavaFX 通过 Maven 创建可运行的 .jar - 实例化 JFXPanel 时应用程序崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用 Maven 创建可运行的 .jar 文件.以下代码显示了主类 (App.java)、实例化 JFXPanel 的类 (ServiceToolEnty.java) 和 pom.xml 文件.

I want to create runnable .jar-file with Maven. The following code shows the main class (App.java), the class where the JFXPanel gets instantiated (ServiceToolEnty.java) and the pom.xml file.

我创建了一个简单的 JFrame,里面有一个按钮(Java Swing 站点).单击按钮后,JFXPanel 应打开 JavaFX 线程以运行 javaFX 代码.

I create a simple JFrame with a button inside (Java Swing site). Once the button has been clicked the JFXPanel should open the JavaFX thread to run javaFX code.

当我在 Eclipse IDE 中运行应用程序时,一切正常.在我使用 Maven 创建 .jar 文件并尝试通过终端(java -jar test-0.0.1-SNAPSHOT.jar)运行它后,出现以下错误消息:

When I run the application in eclipse IDE everything works fine. After I created the .jar file with Maven and I try to run it via terminal (java -jar test-0.0.1-SNAPSHOT.jar), the following error message shows up:

Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: javafx/embed/swing/JFXPanel
    at com.carrier.ccr.test.App$1.actionPerformed(App.java:31)
    at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972)
    at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2313)
    at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
    at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
    at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
    at java.desktop/java.awt.Component.processMouseEvent(Component.java:6626)
    at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3389)
    at java.desktop/java.awt.Component.processEvent(Component.java:6391)
    at java.desktop/java.awt.Container.processEvent(Container.java:2266)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5001)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
    at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948)
    at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4575)
    at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310)
    at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:746)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:744)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:743)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Caused by: java.lang.ClassNotFoundException: javafx.embed.swing.JFXPanel
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
    ... 36 more

App.java:


import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Locale;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
public class App extends JFrame{
 
    public App(){
        setSize(500, 180);
        setVisible(true);
        setLayout(null);
        setLocation(100, 100);

        //Button opens the ServiceTool interface
        JButton masterModeServiceTool = new JButton("Click here");
        masterModeServiceTool.setSize(280, 20);
        masterModeServiceTool.setFont(new Font("Arial",Font.PLAIN,15));
        add(masterModeServiceTool);
        masterModeServiceTool.setVisible(true);
        masterModeServiceTool.setLocation(10, 100);
        masterModeServiceTool.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                try {
                    ServiceToolEntry maServ=new ServiceToolEntry();
                    maServ.main();
                    setVisible(false);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });

    }


    public static void main(String[] args) {
        App mv =new App();
        mv.addWindowListener(new WindowAdapter()
        {
            public void windowClosing (WindowEvent e) {
                System.exit (0);
            }
        });
    }
}

ServiceToolEnty.java(fx 应用程序启动的地方):

ServiceToolEnty.java (where the fx app is starting):


import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class ServiceToolEntry {
    private static void initAndShowGUI() {
        // This method is invoked on the EDT thread
        JFrame frame = new JFrame("Click here");
        final JFXPanel fxPanel = new JFXPanel();
        frame.add(fxPanel);
        frame.setSize(1000, 700);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                initFX(fxPanel);
            }
        });
    }


    private static Scene getScene() {
        Group  root  =  new  Group();
        Scene  scene  =  new  Scene(root, Color.ALICEBLUE);
        Text  text  =  new  Text();

        text.setX(40);
        text.setY(100);
        text.setFont(new Font(25));
        text.setText("Finally it's working");
        root.getChildren().add(text);

        return (scene);
    }


    private static void initFX(JFXPanel fxPanel) {
        Scene scene = getScene();
        fxPanel.setScene(scene);
    }


    public static void main() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                initAndShowGUI();
            }
        });
    }
}

pom.xml 文件:

pom.xml file:


<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.carrier.ccr</groupId>
  <artifactId>test</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <name>test</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
            <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>13</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>13</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-swing</artifactId>
            <version>18-ea+5</version>
        </dependency>
        
  </dependencies>

  <build>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
            <plugin> 
    
               <!-- Building an executable jar -->
    
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-jar-plugin</artifactId>
               <version>3.1.0</version>
               <configuration>
                 <archive>
                   <manifest>
    
                   <!-- give full qualified name of your main class-->
                   <addClasspath>true</addClasspath>
                     <mainClass>com.carrier.ccr.test.App</mainClass>
    
                   </manifest>
                 </archive>
               </configuration>
            </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
        <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
        <plugin>
          <artifactId>maven-site-plugin</artifactId>
          <version>3.7.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
        
        
      </plugins>
    </pluginManagement>
  </build>
</project>

推荐答案

您的代码和打包有很多问题.我现在无法在这里解释所有这些.但是,如果您愿意,我会提出一些您可以尝试使用的替代方案.

You have numerous issues with your code and packaging. I can't really explain them all here now. But I present some alternatives you could try to work with if you wish.

我还将添加通常的警告:除非您真的必须,否则不要混合使用 JavaFX 和 Swing.

I'll also add the usual caveat: don't mix JavaFX and Swing unless you really have to.

替代包装

从最少到最独立的选项(从最不理想到最不理想)排序:

Ordered from the least to most self-contained options (not most to least desirable):

  1. 瘦 jar 没有JavaFX 依赖

  • 要求应用程序在包含预捆绑 JavaFX 模块的 JDK 或 Java 运行时上运行.例如,来自下面提到的分销商.如果使用,请确保选择他们的 JDK 发行版,其中 包括 JavaFX:

您无需将 JavaFX 依赖项放入您的 Maven 项目中,因为它们已在底层平台中可用.

You don't need to put JavaFX dependencies in your Maven project as they are already available in the underlying platform.

如果它是一个简单的应用程序,除了标准的JDK和JavaFX之外没有任何其他依赖项,那么您可以将该应用程序打包为一个没有依赖项的可执行jar.

If it is a simple application, without any other dependencies than the standard JDK and JavaFX, then you can package the application as an executable jar with no dependencies.

阴影脂肪"jar(或 zip)没有JavaFX 依赖项

Shaded "fat" jar (or zip) without JavaFX dependencies

  • 如果您有非 javafx 依赖项,您可以使用fat"解决方案中的信息;带有 JavaFX 依赖项的 jar 或不带 JRE 的 zip.
    • 不要将 JavaFX 依赖项放在您的 Maven 项目依赖项列表中.
    • 确保您和您的用户始终使用包含 JavaFX 的 JDK 或 Java 运行时.

    阴影脂肪"jar (jar) with JavaFX 依赖

    Shaded "fat" jar (jar) with JavaFX dependencies

    不带 JRE 的压缩包(zip、tar、tar.gz、tar.bz2)

    Zip without JRE (zip, tar, tar.gz, tar.bz2)

    • create a maven assembly (this solution).

    使用 JRE 压缩(zip、tar、tar.gz、tar.bz2)

    Zip with JRE (zip, tar, tar.gz, tar.bz2)

    • 使用 jlink创建运行时映像目录.
    • 使用程序集创建运行时映像的 zip.
    • use jlink to create a runtime image directory.
    • create a zip of the runtime image with an assembly.

    Windows exe(exe)

    Windows exe (exe)

    本机安装程序(msi、dmg、app、rpm、deb)

    Native installer (msi, dmg, app, rpm, deb)

    就用户的易用性而言,我推荐后者捆绑了可运行的 Java 运行时:本机安装程序、带有 JRE 的 Zip 或 Windows exe.

    In terms of ease of use for users, I'd recommend the later ones which bundle a working Java runtime: either a Native installer, Zip with JRE, or Windows exe.

    我认为要求用户安装有效 JRE 的解决方案对于许多应用程序来说不太理想.

    I think the solutions which require the user to have a valid JRE installed are less desirable for many applications.

    • 由于没有捆绑的 JRE,确保存在正确的 JRE 并正确配置的艰巨工作转移到每个用户而不是开发人员身上.
    • Maven 阴影脂肪"JavaFX 开发团队不支持包含 JavaFX 依赖项的 jar 选项.

    对于 Maven 用户

    • jlink 可以从 OpenJFX JavaFX Maven 插件调用.
      • jlink can be invoked from the OpenJFX JavaFX Maven plugin.
        • Currently the Apache Maven jlink plugin does not work with JavaFX, hopefully that will be fixed.
        • jpackage 也可以创建图片,和 jlink 一样.
        • 如果创建本机安装程序,我建议让 jpackage 处理链接和打包(如果您不这样做,jpackage 会警告您).
        • 在windows应用的一些选项上,我发现jlink默认没有把需要的图标放在正确的位置,导致奇怪且难以追踪jpackage 执行链接时未出现的问题.

        这个答案的其余部分完全集中在没有 JRE 选项的 Zip 上.

        The rest of this answer focuses purely on the Zip without JRE option.

        请参阅答案末尾的自述文件,其中描述了这是什么以及如何使用它.如果这不是您想要的,请忽略它并尝试以另一种方式解决您的问题.

        See the readme at the end of the answer which describes what this is and how to use it. If it is not what you are looking for, just ignore it and try to solve your issues another way.

        解决方案是不是一个可执行的jar.相反,它是一组以 jar 格式打包的 Java 模块,通过启动器脚本执行并组装成压缩存档文件.

        The solution is not an executable jar. Instead, it is a set of java modules packaged in jar format, executed via a launcher script and assembled into a compressed archive file.

        • 它要求在目标机器上安装 JRE 17+.

        • It requires that JRE 17+ be installed on the target machine.

        该应用程序仅打包用于在 Intel Mac 上执行(至少当它已在 Intel Mac 上构建时).

        The application is only packaged for executing on an Intel Mac (at least when it has been built on an Intel Mac).

        • 可以为其他平台打包,但这超出了我在这里讨论的范围.

        Swing<->JavaFX 集成

        该解决方案适用于 Swing+JavaFX 应用程序.通常我不会推荐这样的配置,但是在这里提出它是因为这就是问题所问的问题.Swing<->JavaFX 集成代码遵循 Oracle 教程中提供的结构和指南:将 JavaFX 集成到 Swing 应用程序中.

        The solution is for a Swing+JavaFX application. Normally I wouldn't recommend such a configuration, however it is presented here because that is what the question asked about. The Swing<->JavaFX integration code follows the structure and guidelines provided in Oracle's tutorial: Integrating JavaFX into Swing Applications.

        如果您的应用程序中没有 Swing,请删除 Swing 应用程序、模块定义中的 javafx.swing 要求和 Maven 中的 javafx-swing 依赖项,并重新配置启动器脚本以直接调用 JavaFX HelloApplication 和所有内容将适用于没有 Swing 的纯 JavaFX 应用程序发行版.

        If you don't have Swing in your application, remove the Swing application, the javafx.swing requirement in the module definition and the javafx-swing dependency from Maven, and reconfigure the launcher script to directly call the JavaFX HelloApplication and everything will work fine for a pure JavaFX application distribution without Swing.

        文件树

        $ tree
        ├── pom.xml
        ├── readme.md
        └── src
            ├── assembly
            │   └── bin.xml
            └── main
                ├── command
                │   └── swingfx.sh
                ├── java
                │   ├── com
                │   │   └── example
                │   │       └── swingfx
                │   │           ├── HelloApplication.java
                │   │           ├── HelloController.java
                │   │           └── SwingApp.java
                │   └── module-info.java
                └── resources
                    └── com
                        └── example
                            └── swingfx
                                └── hello-view.fxml
        

        我没有提供 JavaFX FXML 和控制器代码,因为它们与解决方案无关,它们只是由您可以在任何基本 FXML 教程中找到的标准代码构成.

        I skipped providing the JavaFX FXML and Controller code because they aren't relevant to the solution, they are just formed from standard code that you can find in any basic FXML tutorial.

        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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
            <modelVersion>4.0.0</modelVersion>
        
            <groupId>com.example</groupId>
            <artifactId>SwingFX</artifactId>
            <version>1.0-SNAPSHOT</version>
            <name>SwingFX</name>
        
            <properties>
                <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
                <javafx.version>17.0.1</javafx.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>
                <dependency>
                    <groupId>org.openjfx</groupId>
                    <artifactId>javafx-swing</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>
                            <source>17</source>
                            <target>17</target>
                        </configuration>
                    </plugin>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-assembly-plugin</artifactId>
                        <version>3.3.0</version>
                        <configuration>
                            <descriptors>
                                <descriptor>src/assembly/bin.xml</descriptor>
                            </descriptors>
                        </configuration>
                        <executions>
                            <execution>
                                <phase>package</phase>
                                <goals>
                                    <goal>single</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </project>
        

        module-info.java

        module com.example.swingfx {
            requires javafx.controls;
            requires javafx.fxml;
            requires javafx.swing;
        
            opens com.example.swingfx to javafx.fxml;
            exports com.example.swingfx;
        }
        

        SwingApp.java

        package com.example.swingfx;
        
        import javafx.application.Platform;
        import javafx.embed.swing.JFXPanel;
        
        import javax.swing.*;
        import java.awt.*;
        
        public class SwingApp {
        
            private static void initAndShowGUI() {
                JFrame frame = new JFrame("Swing Main App JFrame");
                frame.setSize(500, 180);
                frame.setVisible(true);
                frame.setLayout(null);
                frame.setLocation(100, 100);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
                //Button opens the ServiceTool interface
                JButton toolLauncher = new JButton("Launch JavaFX Tool");
                toolLauncher.setSize(280, 20);
                toolLauncher.setFont(new Font("Arial", Font.PLAIN, 15));
                toolLauncher.setVisible(true);
                toolLauncher.setLocation(10, 100);
                toolLauncher.addActionListener(e -> launchFXTool());
                frame.add(toolLauncher);
            }
        
            private static void launchFXTool() {
                try {
                    // This method is invoked on the EDT thread
                    // The method creates a new frame and JavaFX scene whenever it is invoked.
                    // If preferred and only one instance is required, then cache the JFrame
                    // on first launch, then show and focus the existing JFrame when the tool is relaunched.
                    JFrame frame = new JFrame("Swing JFrame with JavaFX scene content");
                    final JFXPanel fxPanel = new JFXPanel();
                    frame.add(fxPanel);
                    frame.setSize(300, 200);
                    frame.setVisible(true);
        
                    Platform.runLater(() -> {
                        // This logic is invoked on the JavaFX thread
                        try {
                            fxPanel.setScene(
                                    HelloApplication.createScene()
                            );
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        
            public static void main(String[] args) {
                SwingUtilities.invokeLater(SwingApp::initAndShowGUI);
            }
        }
        

        HelloApplication.java

        package com.example.swingfx;
        
        import javafx.application.Application;
        import javafx.fxml.FXMLLoader;
        import javafx.scene.Scene;
        import javafx.stage.Stage;
        
        import java.io.IOException;
        
        public class HelloApplication extends Application {
            @Override
            public void start(Stage stage) throws IOException {
                stage.setTitle("Hello!");
                stage.setScene(createScene());
                stage.show();
            }
        
            public static Scene createScene() throws IOException {
                FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
                return new Scene(fxmlLoader.load(), 320, 240);
            }
        
            public static void main(String[] args) {
                launch(args);
            }
        }
        

        swingfx.sh

        #!/bin/sh
        VM_OPTIONS=
        DIR=`dirname $0`
        MODULE_PATH=$DIR/../lib
        MAIN_CLASS=com.example.swingfx/com.example.swingfx.SwingApp 
        # if desired you could add a check to ensure a compatible java version is installed and print a friendly error message if not.
        # launches a java app with the given vm options and module path, passing the arguments provided to this script to the app.
        java $VM_OPTIONS -p $MODULE_PATH -m $MAIN_CLASS "$@"
        

        bin.xml

        <assembly>
            <id>bin</id>
            <formats>
                <format>tar.gz</format>
                <format>zip</format>
            </formats>
            <dependencySets>
                <dependencySet>
                    <scope>runtime</scope>
                    <outputDirectory>lib</outputDirectory>
                </dependencySet>
            </dependencySets>
            <fileSets>
                <fileSet>
                    <directory>src/main/command</directory>
                    <outputDirectory>bin</outputDirectory>
                    <includes>
                        <include>*.sh</include>
                        <include>*.bat</include>
                    </includes>
                    <fileMode>0755</fileMode>
                </fileSet>
            </fileSets>
        </assembly>
        

        readme.md

        与 JavaFX 集成的 Swing 应用程序示例.该应用程序构建为 Java 模块应用程序.

        Example of a Swing application integrated with JavaFX. The application is built as a Java module application.

        • Java JDK 17+
        • Maven 3.8+
        • Java JRE 17+
        • Mac OS X 英特尔

        构建并打包应用程序:

        mvn package
        

        构建将创建以下文件:

        target/SwingFX-1.0-SNAPSHOT-bin.tar.gz
        

        执行说明

        1. 从存档中提取应用程序二进制文件.

        1. Extract the application binary from the archive.

        tar xzvf SwingFX-1.0-SNAPSHOT-bin.tar.gz
        

      • 运行应用程序:

      • Run the application:

        SwingFX-1.0-SNAPSHOT/bin/swingfx.sh 
        

      • 分发内容

        $ tar xvzf SwingFX-1.0-SNAPSHOT-bin.tar.gz 
        x SwingFX-1.0-SNAPSHOT/bin/swingfx.sh
        x SwingFX-1.0-SNAPSHOT/lib/javafx-controls-17.0.1.jar
        x SwingFX-1.0-SNAPSHOT/lib/javafx-controls-17.0.1-mac.jar
        x SwingFX-1.0-SNAPSHOT/lib/javafx-graphics-17.0.1.jar
        x SwingFX-1.0-SNAPSHOT/lib/javafx-graphics-17.0.1-mac.jar
        x SwingFX-1.0-SNAPSHOT/lib/javafx-base-17.0.1.jar
        x SwingFX-1.0-SNAPSHOT/lib/javafx-base-17.0.1-mac.jar
        x SwingFX-1.0-SNAPSHOT/lib/javafx-fxml-17.0.1.jar
        x SwingFX-1.0-SNAPSHOT/lib/javafx-fxml-17.0.1-mac.jar
        x SwingFX-1.0-SNAPSHOT/lib/javafx-swing-17.0.1.jar
        x SwingFX-1.0-SNAPSHOT/lib/javafx-swing-17.0.1-mac.jar
        x SwingFX-1.0-SNAPSHOT/lib/SwingFX-1.0-SNAPSHOT.jar
        

        问题排查

        如果你看到下面的错误,java没有安装并且在默认路径上:

        Troubleshooting

        If you see the following error, java is not installed and on the default path:

        -bash: java: command not found
        

        如果您看到如下错误:

        Caused by: java.lang.module.InvalidModuleDescriptorException: Unsupported major.minor version 61.0
        

        Java 已安装但不是 Java 17+,您需要将 Java 安装升级到更高版本,您可以使用 java -version

        Java is installed but it is not Java 17+, you need to upgrade the Java installation to a later version, you can check the current version using java -version

        这篇关于使用 Java Swing 和集成的 JavaFX 通过 Maven 创建可运行的 .jar - 实例化 JFXPanel 时应用程序崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆