С момента появления модулей существует как минимум три различных способа настройки приложения JavaFX:
Поместите все на путь модуля, включая модули JavaFX и ваш модуль. .
- Это идеальная ситуация, но не всегда возможная / жизнеспособная (например, из-за несовместимых зависимостей).
Поместите модули JavaFX на путь к модулю и ваш собственный код на пути к классам.
- Эта конфигурация требует использования
--add-modules
.
Положите все на путь к классу, включая модули JavaFX и ваш собственный код.
- При такой конфигурации ваш основной класс не может быть подтипом
Application
. В противном случае вы получите ошибку, о которой вы упоминали в своем вопросе: « Ошибка: отсутствуют компоненты времени выполнения JavaFX, и они необходимы для запуска этого приложения ». - Эта конфигурация позволяет легко использовать JAR-файлы fat / uber.
Командная строка, используемая с ProcessBuilder
, будет зависеть от конфигурации вашего приложения. Вы также должны принять во внимание любые другие параметры, переданные в командной строке, такие как кодировка по умолчанию или локаль. К сожалению, ваш вопрос не содержит достаточно информации, чтобы сказать, что именно 1039 * идет не так. Ошибка, о которой вы упоминаете, заставляет меня думать, что вы используете третью конфигурацию, но я не уверен.
Тем не менее, я приведу несколько примеров запуска одного и того же приложения из приложения; Вы должны быть в состоянии изменить вещи, чтобы соответствовать вашим потребностям. Примечание. Я использовал Java / JavaFX 13.0.1 при тестировании приведенного ниже кода.
Конфигурация # 1
Поместите все в путь к модулю.
module-info. java:
module app {
requires javafx.controls;
exports com.example.app to
javafx.graphics;
}
Main. java:
package com.example.app;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Path;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import static java.lang.System.getProperty;
public class Main extends Application {
private static void launchProcess() {
try {
new ProcessBuilder(
Path.of(getProperty("java.home"), "bin", "java").toString(),
"--module-path",
getProperty("jdk.module.path"),
"--module",
getProperty("jdk.module.main") + "/" + getProperty("jdk.module.main.class"))
.inheritIO()
.start();
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
@Override
public void start(Stage primaryStage) {
Button launchBtn = new Button("Launch process");
launchBtn.setOnAction(
event -> {
event.consume();
launchProcess();
});
primaryStage.setScene(new Scene(new StackPane(launchBtn), 500, 300));
primaryStage.setTitle("Multi-Process Example");
primaryStage.show();
}
}
Командная строка:
java --module-path <PATH> --module app/com.example.app.Main
Замените "<PATH>
" на путь, содержащий как модули JavaFX, так и вышеуказанный модуль.
Конфигурация # 2
Установите модули JavaFX на путь к модулю и ваш код на пути к классам.
Main. java:
package com.example.app;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Path;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import static java.lang.System.getProperty;
public class Main extends Application {
private static void launchProcess() {
try {
new ProcessBuilder(
Path.of(getProperty("java.home"), "bin", "java").toString(),
"--module-path",
getProperty("jdk.module.path"),
"--add-modules",
"javafx.controls",
"--class-path",
getProperty("java.class.path"),
Main.class.getName())
.inheritIO()
.start();
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
@Override
public void start(Stage primaryStage) {
Button launchBtn = new Button("Launch process");
launchBtn.setOnAction(
event -> {
event.consume();
launchProcess();
});
primaryStage.setScene(new Scene(new StackPane(launchBtn), 500, 300));
primaryStage.setTitle("Multi-Process Example");
primaryStage.show();
}
}
Командная строка:
java --module-path <M_PATH> --add-modules javafx.controls --class-path <C_PATH> com.example.app.Main
Замените "<M_PATH>
" на путь, содержащий модули JavaFX, и замените "<C_PATH>
" на путь, содержащий вышеуказанный код.
Конфигурация # 3
Поместите все на путь класса. Обратите внимание, что основной класс (теперь Launcher
) не является подклассом Application
.
Launcher. java:
package com.example.app;
import javafx.application.Application;
public class Launcher {
public static void main(String[] args) {
Application.launch(Main.class, args);
}
}
Main . java:
package com.example.app;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Path;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import static java.lang.System.getProperty;
public class Main extends Application {
private static void launchProcess() {
try {
new ProcessBuilder(
Path.of(getProperty("java.home"), "bin", "java").toString(),
"--class-path",
getProperty("java.class.path"),
Launcher.class.getName())
.inheritIO()
.start();
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
@Override
public void start(Stage primaryStage) {
Button launchBtn = new Button("Launch process");
launchBtn.setOnAction(
event -> {
event.consume();
launchProcess();
});
primaryStage.setScene(new Scene(new StackPane(launchBtn), 500, 300));
primaryStage.setTitle("Multi-Process Example");
primaryStage.show();
}
}
Командная строка:
java --class-path <PATH> com.example.app.Launcher
Заменить "<PATH>
" на путь, содержащий JAR-файлы JavaFX и код выше.