1

これが JavaFX の最初のステップです。リアルタイムの棒グラフをエミュレートし、すべてのセンサーのステータスを表すバーの部分を追加するために毎秒更新する単純なデスクトップ アプリケーションを JavaFx で作成しようとしています (オフ、機能していない、正常に機能している...)。センサーとアプリケーションの両方に情報を送信するために、いくつかのボタン/テキストフィールド/メニュー項目を実装する必要があります。

そのため、キャンバスをシーンに追加する直前にstart()メソッドから呼び出されるメソッドを使用しています。そこからTimerTaskを呼び出して毎秒グラフを描画すると、正常に動作します。これにより、このキャンバスをBorderPaneの中央に設定し、他の要素をペインの別の部分に追加しようとすると、この timerTask が実行されると思われる場合でも、それらの動作は TimerTask の遅延の影響を受けます。別のスレッド。

リアルタイム描画をアプリケーションの残りの部分から別のスレッドに分離するにはどうすればよいですか?? 「TimerTask」とは別のクラスを使用する必要がありますか??

コードは次のようなものです。

@Override
public void start(Stage primaryStage) {
    this.primaryStage = primaryStage;
    BorderPane bp = new BorderPane();
    Group root = new Group();

    // create a canvas node
    Canvas canvas = new Canvas();

    // bind the dimensions when the user resizes the window.
    canvas.widthProperty().bind(primaryStage.widthProperty());
    canvas.heightProperty().bind(primaryStage.heightProperty());

    // obtain the GraphicsContext (drawing surface)
    final GraphicsContext gc = canvas.getGraphicsContext2D();

    //Invoke the real time graph drawing
    draw(gc);

    // add the single node onto the border pane
    bp.setCenter(canvas);
    MenuBar bar = new MenuBar();
    Menu sensorsMenu = new Menu("Sensors");
    bar.getMenus().add(sensors);
    for(int i=0; i<nDetect; i++){
        sensorsMenu.getItems().add(new CheckMenuItem("Sensor " + (i+1)));
    }
    //add the menu bar to top
    bp.setTop(bar);
    root.getChildren().add(bp);

    Scene scene = new Scene(root);
    primaryStage.setScene(scene);
    primaryStage.show();
}

public void draw(GraphicsContext gc){
    c = new SerialPortConection();

    c.establishConnection("COM1", 2400, 8, 1, 1);
    LinkedList<String> resp = null;

        .
        .
        .

    timer = new Timer();
    timer.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            javafx.application.Platform.runLater(new Runnable() {
            @Override
            public void run() {
                //Send request to sensor
                try {
                    resp = c.sendStatusRequest();
                } catch (WrongFormatException ex) {
Logger.getLogger(Sensor.class.getName()).log(Level.SEVERE, null, ex);
                }
                //Update sensor status
                for(int i=0; i<nSensors; i++){
                    sensors.get(i).update(resp.get(37+i));
                }

                //Draw sensors status
                for(int i=0; i<nSensors; i++){
                    sensors.get(i).draw(gc);
                }
                //Paint axis
                .
                .
                .
            }
        });
        }
    }, 0, 1000);
}
4

1 に答える 1

0

この答えを見ることができます:

JavaFX の定期的なバックグラウンド タスク

を使えばTimerTaskOKです。タイマー スレッド (バックグラウンド スレッド) を使用してリクエストを外部サービスに呼び出し、JFX スレッドを使用してグラフィックを更新する必要があります。

    timer.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            // call external service in the background thread
            resp = c.sendStatusRequest();
            javafx.application.Platform.runLater(new Runnable() {
            @Override
            public void run() {
                // update the graphics in the JFX thread
            }
        });
        }
    }, 0, 1000);
于 2015-03-10T10:55:19.043 に答える