简体   繁体   English

JavaFX自动打开新窗口

[英]JavaFX Auto Open new Window

I have A.fxml and B.fxml. 我有A.fxml和B.fxml。 A runing with Java Application override start method. 使用Java Application运行覆盖启动方法。 I want to every 40 min in loop(5 times) { open new stage B.fxml and wait stage.close, if stage close continue loop open new stage B fxml. 我想每40分钟循环一次(5次){打开新阶段B.fxml并等待stage.close,如果阶段关闭继续循环,则打开新阶段B fxml。 Loop this five times. 循环播放五次。 I try timer timertask i could not. 我尝试定时器timertask我无法。 I try JavaFX Service i could not. 我无法尝试JavaFX Service。 I create Mythread extend Thread object. 我创建Mythread扩展Thread对象。 This time i could not control loop for next stage. 这次我无法控制下一阶段的循环。 When for statement start opening 5 stage. 为声明何时开始打开第5阶段。 But i want to loop wait for currentstage is close then go next loop. 但是我想循环等待currentstage关闭然后再进入下一个循环。 This is my fail code; 这是我的失败代码;

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";
}

} }

I need to work more Java multi threads. 我需要工作更多的Java多线程。 But after fix this problem. 但是解决此问题后。 Please explain where I'm doing wrong. 请说明我做错了什么。 In loop write console currentThread name console result "Java Apllication Thread". 在循环中,写控制台currentThread名称控制台结果为“ Java Apllication Thread”。 But i set my thread name "MyThread". 但我将线程名称设置为“ MyThread”。 I'm so confused.My brain gave blue screen error. 我很困惑,我的大脑出现了蓝屏错误。

You've put your System.out.println(currentThread().getName()) statement into Platform.runLater() , which means that it will be executed on JavaFX Application Thread (see JavaDoc ). 您已经将System.out.println(currentThread().getName())语句放入Platform.runLater() ,这意味着它将在JavaFX Application Thread上执行(请参阅JavaDoc )。

Regarding your question about scheduling some task to repeat fixed number of times with predefined rate, this post could help you. 关于您安排一些任务以预定义的速率重复固定次数的问题, 这篇文章可以为您提供帮助。

In loop write console currentThread name console result "Java Apllication Thread". 在循环中,写控制台currentThread名称控制台结果为“ Java Apllication Thread”。 But i set my thread name "MyThread". 但我将线程名称设置为“ MyThread”。 I'm so confused. 我很混乱。

Using Platform.runLater you schedule the Runnable to be executed on the javafx application thread instead of the current thread which allows you to modify the UI, but also results in the current thread being the javafx application thread instead of the thread you call Platform.runLater from... 使用Platform.runLater您可以将Runnable安排在javafx应用程序线程上执行,而不是在当前线程上执行,这使您可以修改UI,但是也会导致当前线程是javafx应用程序线程,而不是您调用Platform.runLater的线程。从...

If you want to continue the "loop" after the window has been closed, you should schedule opening the next window after the last one has been closed. 如果要在关闭窗口继续“循环”,则应安排在关闭最后一个窗口后再打开下一个窗口。 Stage.showAndWait() is a convenient way to wait for the stage to be closed. Stage.showAndWait()是等待舞台关闭的便捷方法。

For scheduling I'd recommend using a ScheduledExecutorService : 对于调度,我建议使用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();
}

I fix this. 我解决这个问题。 I used Timer and TimeTask in my main controller init method. 我在主控制器的init方法中使用了Timer和TimeTask。 And its work. 及其工作。 But same code in app start method or in mian method stage didnt wait. 但是在应用程序启动方法或主方法阶段中的相同代码没有等待。 I used stageshowandwait() method but thread didnt wait. 我使用了stageshowandwait()方法,但是线程没有等待。 But same code woked in main controller init method. 但是相同的代码在主控制器init方法中被唤醒。 Why i dont know. 为什么我不知道。

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