簡體   English   中英

JavaFX自動打開新窗口

[英]JavaFX Auto Open new Window

我有A.fxml和B.fxml。 使用Java Application運行覆蓋啟動方法。 我想每40分鍾循環一次(5次){打開新階段B.fxml並等待stage.close,如果階段關閉繼續循環,則打開新階段B fxml。 循環播放五次。 我嘗試定時器timertask我無法。 我無法嘗試JavaFX Service。 我創建Mythread擴展Thread對象。 這次我無法控制下一階段的循環。 為聲明何時開始打開第5階段。 但是我想循環等待currentstage關閉然后再進入下一個循環。 這是我的失敗代碼;

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 Apllication Thread”。 但我將線程名稱設置為“ MyThread”。 我很困惑,我的大腦出現了藍屏錯誤。

您已經將System.out.println(currentThread().getName())語句放入Platform.runLater() ,這意味着它將在JavaFX Application Thread上執行(請參閱JavaDoc )。

關於您安排一些任務以預定義的速率重復固定次數的問題, 這篇文章可以為您提供幫助。

在循環中,寫控制台currentThread名稱控制台結果為“ Java Apllication Thread”。 但我將線程名稱設置為“ 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();
}

我解決這個問題。 我在主控制器的init方法中使用了Timer和TimeTask。 及其工作。 但是在應用程序啟動方法或主方法階段中的相同代碼沒有等待。 我使用了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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM