Javafx 8 - setVisible()被阻止

时间:2015-09-02 09:49:31

标签: javafx-8

所以这是我的情况: 我使用场景生成器构建了一个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>

所有这些都只是在名为“应用程序”

的软件包下

1 个答案:

答案 0 :(得分:2)

在用户 kleopatra 的一些帮助中,我来自oracle的以下链接:

https://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm

基本上我的问题总结如下:

  

JavaFX场景图,表示图形用户界面   JavaFX应用程序,不是线程安全的,只能访问   并从UI线程修改,也称为JavaFX应用程序   线。 在JavaFX应用程序上实现长时间运行的任务   线程不可避免地使应用程序UI无响应。最好的   练习是在一个或多个后台线程上执行这些任务   让JavaFX Application线程处理用户事件。

希望它有所帮助!