2017-01-31 7 views
0

データベースから値を読み込み、Map<Integer,String>.を返すメソッドがあります。このメソッドはマップを返すのに時間がかかります。JavaFX:プロセスの実行中にすべてのコンポーネントを無効にし、進捗インジケータを表示

時間値が読み込まれるまで進行状況インジケータが必要です(インジケータのようなインジケータが表示されれば、進行状況バーは必要ありません)、画面上に表示されます。表示されます。ここで

public void scanDevice() { 
    ObservableList<TextField> list = FXCollections.observableArrayList(vehicleId, vehicleName, deviceType, 
      offboardBroker1, offboardBroker2, postfixQueue, pKIServer); 
    editedValuesMap.clear(); 
    // devicePlugged = true; 
    if (cbChooseProject.getSelectionModel().getSelectedItem() != null) { 
     try { 
      devicePlugged = dsAdapter.getAdapter(); 
      if (devicePlugged) { 
       if (bScanDevice.isFocused()) { 
        readMap = new HashMap<Integer, String>(); 
        //Process Start 
        readMap = dsAdapter.initScan(); 
        //Process End 

        if (!readMap.isEmpty() && readMap != null) { 
         isWritten = true; 
         isDeviceSideEnabled(); 
         editDeviceContents.setDisable(false); 
         vehicleId.setText(readMap.get(0)); 
         vehicleName.setText(readMap.get(1)); 
         deviceType.setText(readMap.get(2)); 
         offboardBroker1.setText(readMap.get(3)); 
         offboardBroker2.setText(readMap.get(4)); 
         postfixQueue.setText(readMap.get(5)); 
         pKIServer.setText(readMap.get(6)); 
         lContentsSerialNo.setText(readMap.get(7)); 
        } 
       } 
      } 

答えて

0

あなたは次のような方法で、すべてのノードを無効にできますが、あなたも何かがStackPane Sを使用してオーバーレイを実行しながら待機するように欠けている場合があることも好ましい選択。

public void setNodesDiabled(boolean disable, Node... nodes) { 
    for(Node node : nodes) { 
     node.setDisable(disable); 
    } 
} 

任意のノード数を使用すると、プロセスに関連するノードをいくつでも無効にしてから再度有効にすることができます。 node.setDisable(true); node2.setDisable(true);などがいくつかあるように、クリーンアップすることもできます。

この例では、StackPaneオーバーレイがその内部のもの以外をクリックしないため、setNodesDisabled()は必要ありません。背景色は灰色で、アルファベットが70%なので、オーバーレイと言うことができます。

public class ProgressExample extends Application { 

    public StackPane layout, main, progress; 

    public StackPane createProgressPane() { 
     ProgressIndicator indicator = new ProgressIndicator(); 
     indicator.setMaxHeight(50); 
     indicator.setMaxWidth(50); 

     StackPane pane = new StackPane(); 
     pane.setAlignment(Pos.CENTER); 
     pane.setStyle("-fx-background-color: rgba(160,160,160,0.7)"); 
     pane.getChildren().add(indicator); 

     Task<Void> task = new Task<Void>(){ 
      protected Void call() throws Exception { 
       // Your process here. 
       // Any changes to UI components must be inside Platform.runLater() or else it will hang. 
       Thread.sleep(2000); 

       Platform.runLater(() -> { 
        layout.getChildren().remove(pane); 
       }); 
       return null; 
      } 
     }; 
     new Thread(task).start(); 
     return pane; 
    } 

    public StackPane createMainPane() { 
     Label label = new Label("Hello World!"); 
     label.setFont(Font.font("Tahoma", FontWeight.SEMI_BOLD, 16)); 

     Button start = new Button("Start Process"); 
     start.setOnAction(action -> { 
      progress = createProgressPane(); 
      layout.getChildren().add(progress); 
     }); 

     VBox vbox = new VBox(10); 
     vbox.setAlignment(Pos.CENTER); 
     vbox.getChildren().addAll(label, start); 
     vbox.setPadding(new Insets(10,10,10,10)); 

     StackPane pane = new StackPane(); 
     pane.getChildren().add(vbox); 
     return pane; 
    } 

    public void start(Stage stage) throws Exception { 
     main = createMainPane(); 

     layout = new StackPane(); 
     layout.getChildren().add(main); 

     Scene scene = new Scene(layout, 900, 550); 
     stage.setScene(scene); 
     stage.setTitle("Progress Example"); 
     stage.setOnCloseRequest(e -> { 
      Platform.exit(); 
      System.exit(0); 
     }); 
     stage.show(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

私はこの問題は、あなたがNot on FX application threadを得ている理由であるFXのアプリケーションスレッドではありませんTask内部TextField秒の値を変更しようとしているということであると信じています。これを修正するには、Platform.runLater()内のノードを変更する行をif文に次のように記述する必要があります。

if (readMap != null && !readMap.isEmpty()) { // Swap the order, can't check empty if it's null. 
    isWritten = true; 
    isDeviceSideEnabled(); 
    Platform.runLater(() -> { 
     editDeviceContents.setDisable(false); 
     vehicleId.setText(readMap.get(0)); 
     vehicleName.setText(readMap.get(1)); 
     deviceType.setText(readMap.get(2)); 
     offboardBroker1.setText(readMap.get(3)); 
     offboardBroker2.setText(readMap.get(4)); 
     postfixQueue.setText(readMap.get(5)); 
     pKIServer.setText(readMap.get(6)); 
     lContentsSerialNo.setText(readMap.get(7)); 
    }); 
} 
+0

このThread.sleep(2000)の使用方法を教えてください。 私は自分のメソッドで必要な時間を計算してから、その時間にスレッドをスリープさせる必要があります。そして、プロジェクトcontaintsのためにBorderPane Layoutを使用しなければなりません。 以下のエラーが発生しました: スレッド "Thread-5"の例外java.lang.IllegalStateException:FXアプリケーションスレッドではありません。 currentThread = Thread-5 –

+0

この例の 'Thread.sleep(2000);'の使用は単なる例であったためです。時間を取るために内部に何もなければ、進行中のペインはそれをテストしている間は十分に長く見えません。あなたはそれを必要としません。エラーに関しては、 'Task'の中にこれらの行を含めるように質問を編集できますか? FXノードとペインを自分の 'Platform.runLater()'内で変更する行を置く必要があります。 –

+0

Mathews、自分のプロセスを含むコードを追加しました。デバイスから値を読み取るプロセスは、それをUIに表示します。 –

1

はSSCEです:

それを複数回起動することができServiceを使用しています。しかし、それは完全ではありませんが、始めるには何かです。 CSSで

public class Main extends Application { 
    @Override 
    public void start(Stage primaryStage) { 

     BorderPane root = new BorderPane(); 
     Scene scene = new Scene(root, 400, 400); 
     scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm()); 

     Service<Void> serv = new Service<Void>() { 

      @Override 
      protected Task<Void> createTask() { 
       return new Task<Void>() { 

        @Override 
        protected Void call() throws Exception { 
         int maxWork = 10; 
         for (int i = 0; i < maxWork; i++) { 
          Thread.sleep(1000); 
          updateProgress(i + 1, maxWork); 
         } 

         return null; 
        } 

        @Override 
        protected void succeeded() { 
         super.succeeded(); 
         updateProgress(1, 1); 
        } 

        @Override 
        protected void cancelled() { 
         super.cancelled(); 
         updateProgress(1, 1); 
        } 

        @Override 
        protected void failed() { 
         super.failed(); 
         updateProgress(1, 1); 
        } 

       }; 
      } 
     }; 

     ProgressIndicator pi = new ProgressIndicator(); 
     pi.progressProperty().bind(serv.progressProperty()); 


     Button bStart = new Button("Start"); 
     bStart.setOnAction(e -> { 
      serv.reset(); 
      serv.start(); 
     }); 

     root.setCenter(bStart); 
     root.setBottom(pi); 

     primaryStage.setScene(scene); 
     primaryStage.show(); 

     pi.getScene().getRoot().disableProperty().bind(serv.runningProperty()); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

私が追加:

.progress-indicator:disabled { 
    -fx-opacity: 1; 
} 
関連する問題