我最初的fxml(例如home.fxml
)有很多功能,因此完全加载需要大量时间。因此,为了避免程序启动和fxml加载之间的时间间隔,我引入了另外一个fxml(loader.fxml
)和一个gif图像,该图像应该在加载主fxml时出现。问题是我的加载器中的gif图像。fxml不会移动,就像程序中的挂起一样,直到home.fxml被完全加载。为了避免这种情况,我将home.fxml加载移到一个线程中,如下代码所示。
public class UATReportGeneration extends Application {
private static Stage mainStage;
@Override
public void start(Stage stage) {
Parent loaderRoot = null;
try {
loaderRoot = FXMLLoader.load(getClass().getResource("/uatreportgeneration/fxml/Loader.fxml"));
} catch (IOException ex) {
Logger.getLogger(UATReportGeneration.class.getName()).log(Level.SEVERE, null, ex);
}
Scene loadScene = new Scene(loaderRoot);
stage.setScene(loadScene);
stage.initStyle(StageStyle.UNDECORATED);
stage.getIcons().add(new Image(this.getClass().getResourceAsStream("/uatreportgeneration/Images/logo.png")));
stage.show();
mainStage = new Stage(StageStyle.UNDECORATED);
mainStage.setTitle("Upgrade Analysis");
mainStage.getIcons().add(new Image(this.getClass().getResourceAsStream("/uatreportgeneration/Images/logo.png")));
setStage(mainStage);
new Thread(() -> {
Platform.runLater(() -> {
try {
FXMLLoader loader = new FXMLLoader();
Parent root = loader.load(getClass().getResource("/uatreportgeneration/fxml/Home.fxml"));
Scene scene = new Scene(root);
mainStage.setScene(scene);
mainStage.show();
stage.hide();
System.out.println("Stage showing");
// Get current screen of the stage
ObservableList<Screen> screens = Screen.getScreensForRectangle(new Rectangle2D(mainStage.getX(), mainStage.getY(), mainStage.getWidth(), mainStage.getHeight()));
// Change stage properties
Rectangle2D bounds = screens.get(0).getVisualBounds();
mainStage.setX(bounds.getMinX());
mainStage.setY(bounds.getMinY());
mainStage.setWidth(bounds.getWidth());
mainStage.setHeight(bounds.getHeight());
System.out.println("thread complete");
} catch (IOException ex) {
Logger.getLogger(UATReportGeneration.class.getName()).log(Level.SEVERE, null, ex);
}
});
}).start();
}
public static Stage getStage() {
return mainStage;
}
public static void setStage(Stage stage) {
mainStage = stage;
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
但是在这段代码之后,我的程序也挂起了(gif图像没有移动)。如果在platform.runlater()
之外加载fxml,则会得到异常not on FX Thread
。
使用任务
。您需要安排在FX应用程序线程上创建场景和更新舞台。最干净的方法是使用任务
:
Task<Parent> loadTask = new Task<Parent>() {
@Override
public Parent call() throws IOException {
FXMLLoader loader = new FXMLLoader();
Parent root = loader.load(getClass().getResource("/uatreportgeneration/fxml/Home.fxml"));
return root ;
}
};
loadTask.setOnSucceeded(e -> {
Scene scene = new Scene(loadTask.getValue());
mainStage.setScene(scene);
mainStage.show();
stage.hide();
System.out.println("Stage showing");
// Get current screen of the stage
ObservableList<Screen> screens = Screen.getScreensForRectangle(new Rectangle2D(mainStage.getX(), mainStage.getY(), mainStage.getWidth(), mainStage.getHeight()));
// Change stage properties
Rectangle2D bounds = screens.get(0).getVisualBounds();
mainStage.setX(bounds.getMinX());
mainStage.setY(bounds.getMinY());
mainStage.setWidth(bounds.getWidth());
mainStage.setHeight(bounds.getHeight());
System.out.println("thread complete");
});
loadTask.setOnFailed(e -> loadTask.getException().printStackTrace());
Thread thread = new Thread(loadTask);
thread.start();
下面是一个使用这种技术的SSCE:
main.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextField?>
<VBox spacing="10" xmlns:fx="http://javafx.com/fxml/1" fx:controller="MainController">
<padding>
<Insets top="24" left="24" right="24" bottom="24"/>
</padding>
<TextField />
<Button fx:id="button" text="Show Window" onAction="#showWindow"/>
</VBox>
import java.io.IOException;
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
public class MainController {
@FXML
private Button button ;
@FXML
private void showWindow() {
Task<Parent> loadTask = new Task<Parent>() {
@Override
public Parent call() throws IOException, InterruptedException {
// simulate long-loading process:
Thread.sleep(5000);
FXMLLoader loader = new FXMLLoader(getClass().getResource("test.fxml"));
Parent root = loader.load();
return root ;
}
};
loadTask.setOnSucceeded(e -> {
Scene scene = new Scene(loadTask.getValue());
Stage stage = new Stage();
stage.initOwner(button.getScene().getWindow());
stage.setScene(scene);
stage.show();
});
loadTask.setOnFailed(e -> loadTask.getException().printStackTrace());
Thread thread = new Thread(loadTask);
thread.start();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Button?>
<?import javafx.geometry.Insets?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="TestController">
<padding>
<Insets top="24" left="24" right="24" bottom="24"/>
</padding>
<center>
<Label fx:id="label" text="This is a new window"/>
</center>
<bottom>
<Button text="OK" onAction="#closeWindow" BorderPane.alignment="CENTER">
<BorderPane.margin>
<Insets top="5" bottom="5" left="5" right="5"/>
</BorderPane.margin>
</Button>
</bottom>
</BorderPane>
import javafx.fxml.FXML;
import javafx.scene.control.Label;
public class TestController {
@FXML
private Label label ;
@FXML
private void closeWindow() {
label.getScene().getWindow().hide();
}
}
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws IOException {
primaryStage.setScene(new Scene(FXMLLoader.load(getClass().getResource("main.fxml"))));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
请注意,在按下按钮之后,您仍然可以在“加载”FXML所需的五秒钟内键入文本字段,因此UI保持响应。
我的应用程序有选项卡式窗格,所以为了保持fxml文件的可管理性,我有一个包含选项卡的主fxml文件,并为每个其他选项卡单独设置一个fxml。这很好,但出于某种原因,应用程序已经停止加载第二个标签。我试着在主应用程序中单独加载它,效果很好。我尝试创建一个新的fxml文件作为测试,并加载它,这也是有效的。但是,它不会将其加载到第二个选项卡中。此外,控制台没有输出。 第二个: 很抱歉代码太长,并提前感谢
testFX。java: testFXController.java: 测验fxml: 当我运行testFX. java时,系统打印: 这是教授的代码,我似乎无法运行它。我意识到主要问题在代码
问题内容: 我正在尝试设置一个将触发后台进程的php触发文件。 我正在Windows Wampserver环境中执行此操作。 因此,例如,我有运行exec函数的程序,该函数要求解析和执行我的程序。 但是问题是我的文件在停止之前正在等待命令完成运行。后台进程运行约20-30秒,并一直等待所有时间,直到完全完成。 这有意义吗?这是运行命令的文件 基本上,我只想触发backgroundProcess而不
问题内容: 我想在我的应用程序中加载一个fxml文件。我使用下一个代码: 使用一些fxml,一切正常,与其他人我得到此异常: 我不明白为什么会收到这个例外。 谢谢。 编辑: 添加包括示例: 我的父母fxml 我的包含文件: 问题答案: 这是解决方案。 为加载程序添加以下行: 非常糟糕的错误。
我目前正在尝试为我的程序创建一个启动屏幕,因为启动需要一些时间。问题是创建GUI需要一段时间(创建对话、更新表格等)。而且我不能将GUI创建移动到后台线程(如“Task”类),因为我会得到“Not on FXApplication thread”异常。我尝试使用: 以及任务的“调用”方法: 当我在Swing中编写程序时,我可以在EventDispatchThread上显示和更新Splash屏幕,而
我原以为这是一个简单的问题,但我很难找到答案。我有一个与JavaFX场景对象关联的ImageView对象,我想从磁盘加载大图像,并使用ImageView一个接一个地显示它们。我一直在努力寻找一种好方法来反复检查图像对象,当它在后台加载完成时,将其设置为ImageView,然后开始加载新的图像对象。我提出的代码(如下)有时有效,有时无效。我很确定我在JavaFX和线程方面遇到了问题。它有时加载第一个