所以这是我的情况: 我使用场景生成器构建了一个GUI,它工作正常:搜索框和列表。当用户搜索某个值时,结果会在列表中正确显示。
我尝试做的是添加一个进度条,以便在用户进行搜索时显示。为此,我添加了一个用作包装器的窗格,在窗格内部有进度条。
在控制器初始化时,我执行:
progressBarWrapper.setVisible(false)
哪个有效。当我尝试在搜索中激活它时,它不会:
private void search() {
progressBarWrapper.setVisible(true);
String val = searchField.getText();
if (val!= null && !"".equals(val)) {
ObjectList list = service.getObjects(val);
objects.clear();
objects.addAll(list);
}
progressBarWrapper.setVisible(false);
}
我已经意识到,如果我删除包装器设置为隐形的底线,我会让我的进度条显示出来,但只有当我已经有结果时才会显示。
我想这是某种阻塞问题,或者在进行计算时屏幕上的重绘过程被阻止了,但是我不明白发生了什么......有人可以解释它,所以我可以进一步发展吗?只是解释为什么会发生这种行为,以便我能够知道如何解决这个问题。
由于
编辑:我在这里添加一个SSCCE来举例说明
Main.java
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("Main.fxml"));
Parent root = loader.load();
Scene primaryScene = new Scene(root);
primaryStage.setScene(primaryScene);
primaryStage.setTitle("Test");
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
在控制器中,我已经模拟了通过一个内部线程休眠的简单循环获取数据。 MainController.java
package application;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.Pane;
public class MainController {
@FXML
private Button startLoop;
@FXML
private ProgressBar progressBar;
@FXML
private Pane progressBarWrapper;
@FXML
private Label loopCounter;
@FXML
public void initialize() {
System.out.println("Application Started");
progressBarWrapper.setVisible(false);
}
@FXML
private void doLoop() {
progressBarWrapper.setVisible(true);
for (int i = 1; i <= 5; i++) {
progressBar.setProgress(i * 0.2);
loopCounter.setText(String.format("%s loop(s)", i));
try {
Thread.sleep(1000); // 1000 milliseconds is one second.
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
progressBarWrapper.setVisible(false);
}
}
观点: Main.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.*?>
<?import javafx.scene.text.*?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainController">
<children>
<Button fx:id="startLoop" layoutX="258.0" layoutY="14.0" mnemonicParsing="false" onAction="#doLoop" prefHeight="80.0" prefWidth="84.0" text="START LOOP" />
<Label fx:id="loopCounter" layoutX="286.0" layoutY="165.0" text="0">
<font>
<Font name="System Bold" size="48.0" />
</font>
</Label>
<Pane fx:id="progressBarWrapper" layoutX="461.0" layoutY="297.0" prefHeight="400.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<ProgressBar fx:id="progressBar" layoutX="200.0" layoutY="191.0" prefWidth="200.0" progress="0.0">
<cursor>
<Cursor fx:constant="WAIT" />
</cursor>
</ProgressBar>
</children>
</Pane>
</children>
</AnchorPane>
所有这些都只是在名为“应用程序”
的软件包下答案 0 :(得分:2)
在用户 kleopatra 的一些帮助中,我来自oracle的以下链接:
https://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm
基本上我的问题总结如下:
JavaFX场景图,表示图形用户界面 JavaFX应用程序,不是线程安全的,只能访问 并从UI线程修改,也称为JavaFX应用程序 线。 在JavaFX应用程序上实现长时间运行的任务 线程不可避免地使应用程序UI无响应。最好的 练习是在一个或多个后台线程上执行这些任务 让JavaFX Application线程处理用户事件。
希望它有所帮助!