Gradle 如何将 VM 选项添加到 运行 并在 javafx 11 idea 上部署 jfoenix?

Gradle how to add VM option to run and deploy jfoenix on javafx 11 idea?

我正在使用 javafx 11.0.2 和 java 11.0.3 为了发现 'gradle' 我下载了这个项目 https://github.com/fthdgn/java11-javafx-demo 并且当我像这样在 main.fxml 中添加 jfoenix 控件时

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.*?>
<?import com.jfoenix.controls.JFXTextField?>
<?import com.jfoenix.controls.JFXButton?>
<?import com.jfoenix.controls.JFXTabPane?>
<?import javafx.scene.control.Tab?>
<AnchorPane xmlns="http://javafx.com/javafx/8.0.121"
            xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.fthdgn.app.controller.MainController">
    <VBox alignment="CENTER" spacing="10.0" AnchorPane.bottomAnchor="10"
          AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10" fx:id="vbox">
        <TextField fx:id="inputTextField"/>
        <Button mnemonicParsing="false" onAction="#reveseButtonClicked" text="Reverse"/>
        <TextField fx:id="outputTextField"/>
        <JFXTextField fx:id="tf"/>
        <JFXButton text="AZUL" fx:id="button"/>
        <JFXTabPane>
            <Tab>
            </Tab>
        </JFXTabPane>

    </VBox>
</AnchorPane>

我遇到了这个著名的错误

Caused by: java.lang.IllegalAccessError: class com.jfoenix.skins.JFXTabPaneSkin (in module com.jfoenix) cannot access class com.sun.javafx.scene.control.behavior.TabPaneBehavior (in module javafx.controls) because module javafx.controls does not export com.sun.javafx.scene.control.behavior to module com.jfoenix

我编辑了 build.gradle 以添加一些 jvm 选项(用于模块应用程序),如下所示

plugins {
    id 'java'
    id 'application'
    id 'com.zyxist.chainsaw' version '0.3.1'
    id 'org.beryx.jlink' version '2.15.1'
}
compileJava.options.encoding = 'UTF-8'

import org.gradle.internal.jvm.Jvm
import org.gradle.internal.os.OperatingSystem

group 'com.fthdgn'
version '1.0-SNAPSHOT'

sourceCompatibility = 11
targetCompatibility = 11

repositories {
    mavenCentral()
}

mainClassName = mainClass

def currentOS = OperatingSystem.current()
def platform
if (currentOS.isWindows()) {
    platform = 'win'
} else if (currentOS.isLinux()) {
    platform = 'linux'
} else if (currentOS.isMacOsX()) {
    platform = 'mac'
}

jlink {
    javaHome.set(Jvm.current().getJavaHome().getAbsolutePath())

}

dependencies {
    implementation "org.openjfx:javafx-base:11:${platform}"
    implementation "org.openjfx:javafx-graphics:11:${platform}"
    implementation "org.openjfx:javafx-controls:11:${platform}"
    implementation "org.openjfx:javafx-fxml:11:${platform}"
    compile group: 'com.jfoenix', name: 'jfoenix', version: '9.0.9'


}

run {
    jvmArgs += ['--add-exports', 'javafx.controls/com.sun.javafx.scene.control.behavior=com.jfoenix']
    jvmArgs += ['--add-exports', 'javafx.controls/com.sun.javafx.scene.control=com.jfoenix']
    jvmArgs += ['--add-exports', 'javafx.base/com.sun.javafx.binding=com.jfoenix']
    jvmArgs += ['--add-exports', 'javafx.graphics/com.sun.javafx.stage=com.jfoenix']
    jvmArgs += ['--add-exports', 'javafx.base/com.sun.javafx.event=com.jfoenix']

}


我刚刚添加了

run {
    jvmArgs += ['--add-exports', 'javafx.controls/com.sun.javafx.scene.control.behavior=com.jfoenix']
    jvmArgs += ['--add-exports', 'javafx.controls/com.sun.javafx.scene.control=com.jfoenix']
    jvmArgs += ['--add-exports', 'javafx.base/com.sun.javafx.binding=com.jfoenix']
    jvmArgs += ['--add-exports', 'javafx.graphics/com.sun.javafx.stage=com.jfoenix']
    jvmArgs += ['--add-exports', 'javafx.base/com.sun.javafx.event=com.jfoenix']

}


和 运行 就像一个魅力,但这对部署来说是无所不能的,我该如何设置这个 jvmArgs 以便所有任务在 gradle 和 javafx 11 中使用 jfoenix和 java 11 ?

module com.fthdgn.app {
    requires javafx.controls;
    requires javafx.fxml;
    requires transitive com.jfoenix;
    opens com.fthdgn.app to javafx.graphics;
    opens com.fthdgn.app.controller to javafx.fxml;
}

您可以遵循 JavaFX 11+ 的 documentation,带有 Gradle 的模块化部分。

有一个 sample that makes use of the JavaFX gradle plugin, to deal with the JavaFX dependencies and the build and run tasks, and the Jlink 插件,用于处理自定义图像的部署 运行time。

您所要做的就是将 Jfoenix 依赖项添加到该项目,相应地修改其源代码,最后在 runjlink 任务中包含所需的 jvmArgs,像这样:

plugins {
  id 'application'
  id 'org.openjfx.javafxplugin' version '0.0.8'
  id 'org.beryx.jlink' version '2.15.1'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation group: 'com.jfoenix', name: 'jfoenix', version: '9.0.9'
}

javafx {
    version = "13"
    modules = [ 'javafx.controls', 'javafx.fxml' ]
}

run {
    jvmArgs = [
            "--add-exports=javafx.controls/com.sun.javafx.scene.control.behavior=com.jfoenix",
            "--add-exports=javafx.controls/com.sun.javafx.scene.control=com.jfoenix",
            "--add-exports=javafx.base/com.sun.javafx.binding=com.jfoenix",
            "--add-exports=javafx.graphics/com.sun.javafx.stage=com.jfoenix",
            "--add-exports=javafx.controls/com.sun.javafx.scene.control.behavior=com.jfoenix",
    ]
}

jlink {
    launcher {
        name = 'hellofx'
        jvmArgs = [
                "--add-exports=javafx.controls/com.sun.javafx.scene.control.behavior=com.jfoenix",
                "--add-exports=javafx.controls/com.sun.javafx.scene.control=com.jfoenix",
                "--add-exports=javafx.base/com.sun.javafx.binding=com.jfoenix",
                "--add-exports=javafx.graphics/com.sun.javafx.stage=com.jfoenix",
                "--add-exports=javafx.controls/com.sun.javafx.scene.control.behavior=com.jfoenix",
        ]
    }
}

mainClassName = "$moduleName/org.openjfx.MainApp"

现在您可以 运行 您的项目:

./gradlew run

并创建 运行时间图像:

./gradlew jlink

构建完成后,您可以从脚本中运行它:

build/image/bin/hellofx

这对我在 JDK 16:

时不起作用
run {
    jvmArgs = [
            "--add-exports=javafx.controls/com.sun.javafx.scene.control.behavior=com.jfoenix",
            "--add-exports=javafx.controls/com.sun.javafx.scene.control=com.jfoenix",
            "--add-exports=javafx.base/com.sun.javafx.binding=com.jfoenix",
            "--add-exports=javafx.graphics/com.sun.javafx.stage=com.jfoenix",
            "--add-exports=javafx.controls/com.sun.javafx.scene.control.behavior=com.jfoenix",
    ]
}   

有效的是

run {
    jvmArgs = [
            "--add-opens=java.base/java.lang.reflect=com.jfoenix",
            "--add-opens=java.base/java.lang.reflect=com.jfoenix",
            "--add-opens=javafx.controls/com.sun.javafx.scene.control.behavior=com.jfoenix",
            "--add-opens=javafx.base/com.sun.javafx.binding=com.jfoenix",
            "--add-opens=javafx.graphics/com.sun.javafx.stage=com.jfoenix",
            "--add-opens=javafx.base/com.sun.javafx.event=com.jfoenix",
    ]
}

与 Jlink VM args 相同