【问题标题】:JavaFX Auto Open new WindowJavaFX 自动打开新窗口
【发布时间】:2017-08-26 07:46:55
【问题描述】:

我有 A.fxml 和 B.fxml。使用 Java 应用程序覆盖启动方法运行。我想每40分钟循环一次(5次){打开新阶段B.fxml并等待stage.close,如果阶段关闭继续循环打开新阶段B fxml。循环这个五次。我尝试计时器 timertask 我做不到。我尝试了 JavaFX 服务,但我做不到。我创建 Mythread 扩展 Thread 对象。这次我无法控制下一阶段的循环。当 for 语句开始打开 ​​5 阶段。但我想循环等待当前阶段关闭然后进入下一个循环。这是我的失败代码;

public class Driver extends Application {

public static Stage stage;

@Override
public void start(Stage primaryStage) throws Exception {
    FXMLLoader loader = new FXMLLoader(getClass().getResource(View.SETTINGS));
    Parent root = loader.load();
    Scene scene = new Scene(root);
    stage = primaryStage;
    stage.setScene(scene);
    stage.setTitle("Info Library");
    stage.setResizable(false);
    stage.show();
    RandomQuestionThread thread = new RandomQuestionThread();
    if (DBContext.settings.isAbbreviation() || DBContext.settings.isTranslation()) {
        thread.start();
    }
}

public static void main(String[] args) throws InterruptedException {
    DBContext.settings = DBContext.getInstance().settings().getSettings();

    launch(args);
    HibernateUtil.getSessionFactory().close();
}

}

public class RandomQuestionThread extends Thread {
Thread randomThread = new Thread(this);
private String fxml;
private static String TITLE;


@Override
public void run() {
    while (true) {
        try {
            Thread.sleep(DBContext.settings.getAutoQuestionTime() * 6000);
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        for (int i = 0; i<DBContext.settings.getAutoQuestionCount(); i++) {
            randomFxml();
            Platform.runLater(()->{
                Parent root = null;
                try {
                    root = new FXMLLoader(getClass().getResource(fxml)).load();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                Stage stage = new Stage();
                stage.setScene(new Scene(root));
                stage.setTitle(TITLE);
                stage.show();
                System.out.println(currentThread().getName());
            });
        }
    }
}

private void randomFxml() {
    int start = 0;
    if (DBContext.settings.isTranslation() && DBContext.settings.isAbbreviation()) {
        start = new Random().nextInt(2);
    } else if (DBContext.settings.isTranslation()) {
        start = 1;
    }

    switch (start) {
    case 0:
        fxml = View.ABBREVIATION;
        break;
    case 1:
        fxml = View.TRANSLATION;
        break;

    default:
        break;
    }
    if (start == 0) {
        TITLE = "KISALTMA SORUSU";
    } else TITLE = "ÇEVİRİ SORUSU";
}

}

我需要处理更多的 Java 多线程。但是在解决了这个问题之后。请解释我在哪里做错了。在循环中写入控制台 currentThread 名称控制台结果“Java 应用程序线程”。但我将我的线程名称设置为“MyThread”。我很困惑。我的大脑出现蓝屏错误。

【问题讨论】:

    标签: java multithreading javafx javafx-8


    【解决方案1】:

    您已将System.out.println(currentThread().getName()) 语句放入Platform.runLater(),这意味着它将在JavaFX 应用程序线程 上执行(参见JavaDoc)。

    关于您关于安排某些任务以预定义的速率重复固定次数的问题,this post 可以帮助您。

    【讨论】:

      【解决方案2】:

      在循环中写入控制台 currentThread 名称控制台结果“Java 应用线程”。但我将我的线程名称设置为“MyThread”。我很困惑。

      使用Platform.runLater 可以安排Runnable 在javafx 应用程序线程而不是当前线程上执行,这允许您修改UI,但也会导致当前线程是javafx 应用程序线程而不是线程你打电话给Platform.runLater...

      如果您想在窗口关闭后继续“循环”,您应该安排在最后一个窗口关闭后打开下一个窗口。 Stage.showAndWait() 是等待舞台关闭的便捷方式。

      对于日程安排,我建议使用ScheduledExecutorService

      private ScheduledExecutorService executor;
      
      @Override
      public void stop() throws Exception {
          // stop executor to allow the JVM to terminate
          executor.shutdownNow();
      }
      
      @Override
      public void init() throws Exception {
          executor = Executors.newSingleThreadScheduledExecutor();
      }
      
      @Override
      public void start(Stage primaryStage) {
          Button btn = new Button("Start");
          btn.setOnAction(new EventHandler<ActionEvent>() {
      
              public void handle(ActionEvent event) {
                  // just display a "empty" scene
                  Scene scene = new Scene(new Pane(), 100, 100);
                  Stage stage = new Stage();
                  stage.setScene(scene);
      
                  // schedule showing the stage after 5 sec
                  executor.schedule(new Runnable() {
      
                      private int openCount = 5;
      
                      @Override
                      public void run() {
                          Platform.runLater(() -> {
                              stage.showAndWait();
                              if (--openCount > 0) {
                                  // show again after 5 sec unless the window was already opened 5 times
                                  executor.schedule(this, 5, TimeUnit.SECONDS);
                              }
                          });
                      }
      
                  }, 5, TimeUnit.SECONDS);
      
              }
          });
      
          StackPane root = new StackPane();
          root.getChildren().add(btn);
      
          Scene scene = new Scene(root);
      
          primaryStage.setScene(scene);
          primaryStage.show();
      }
      

      【讨论】:

      • showandwait() 在应用启动方法或主方法中不起作用。阶段没有等待或线程,循环我现在在主控制器初始化方法中尝试相同的代码。这个时间阶段等待或循环或线程。问题已解决,但我不明白为什么。
      • @VolkanOkçu 我所知道的showAndWait 的唯一限制是:a)从应用程序线程调用它,b)不能在初级阶段调用。
      【解决方案3】:

      我解决了这个问题。我在我的主控制器初始化方法中使用了 Timer 和 TimeTask。及其工作。但是应用程序启动方法或 mian 方法阶段中的相同代码没有等待。我使用了 stageshowandwait() 方法,但线程没有等待。但是在主控制器的 init 方法中唤醒了相同的代码。为什么我不知道。

      Timer timer = new Timer();
          TimerTask timerTask = new TimerTask() {
      
              @Override
              public void run() {
                  Platform.runLater(()->{
                      for (int i = 0; i<4; i++) {
                          Parent root = null;
                          try {
                              root = new FXMLLoader(getClass().getResource(View.ABBREVIATION)).load();
                          } catch (IOException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                          }
                          Stage stage = new Stage();
                          stage.setScene(new Scene(root));
                          stage.setTitle("deneme");
                          stage.showAndWait();
                      }
                  });
              }
          };
      
          timer.schedule(timerTask, 6000);
      

      【讨论】:

        猜你喜欢
        • 2013-02-09
        • 1970-01-01
        • 1970-01-01
        • 2015-07-15
        • 2015-07-16
        • 1970-01-01
        • 1970-01-01
        • 2014-10-19
        • 1970-01-01
        相关资源
        最近更新 更多