2017-03-31 12 views
0

私はA.fxmlとB.fxmlを持っています。 Javaアプリケーションを使用したランニングは、startメソッドをオーバーライドします。私は40分ごとにループ(5回){新しいステージB.fxmlを開き、ステージをクローズします。これを5回繰り返します。私はタイマーを試してみてください私はできませんでした。私はJavaFXサービスを試してみることができませんでした。 Mythread extends Threadオブジェクトを作成します。今回は、次の段階でループをコントロールできませんでした。 for文を開始すると5段階が開きます。しかし、私は現在のステージが近づいているのを待っています。これは私の失敗コードです。JavaFX Auto Open新しいウィンドウ

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 nameコンソールの結果は "Javaアプリケーションスレッド"です。しかし、私はスレッド名 "MyThread"を設定しました。私はとても混乱しています。私の脳はブルースクリーンエラーを起こしました。

答えて

0

私はこの問題を解決します。私は私のメインコントローラのinitメソッドで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); 
0

あなたはそれがのJavaFXアプリケーションスレッドJavaDocを参照)上で実行されることを意味し、Platform.runLater()にあなたのSystem.out.println(currentThread().getName())文を入れています。

予め定められた割合で一定回数繰り返すようにタスクをスケジューリングすることに関するご質問については、this postがお手伝いします。

0

ループ書き込みコンソールcurrentThread名コンソールの結果「Javaアプリケーションスレッド」。しかし、私はスレッド名 "MyThread"を設定しました。私は困惑している。あなたが代わりにあなたがUIを変更することができ、現在のスレッドのJavaFXアプリケーションのスレッド上で実行されるRunnableのスケジュールを設定するだけでなく、あなたの代わりに、スレッドのJavaFXアプリケーションのスレッドであること、現在のスレッドになりPlatform.runLaterを使用して

あなたは、ウィンドウが閉じられた後に「ループ」を継続したい場合は、最後の1が閉じられた後、あなたは次のウィンドウを開いてスケジュールする必要があり

...から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(); 
} 
+0

showandwait()は、アプリケーションの開始メソッドまたはメインメソッドで機能しませんでした。ステージが待たされたりスレッドされたりしなかったので、今度はメインコントローラのinitメソッドで同じコードを試してみてください。この時間ステージは待っていたか、ループしていたかスレッドです。問題は修正されましたが、理由はわかりません。 –

+0

@VolkanOkçu私が知っている 'showAndWait'の唯一の制限は次のとおりです:a)アプリケーションスレッドから呼び出し、b)プライマリステージで呼び出すことができません。 – fabian

関連する問題