TilePaneに最大9個のパネルをロードしたいと思います。各ペインに対して、私はコンテンツの計算(約300ms)と第2のパネル(約500ms)を構築する必要があります。私が望むのは、計算後にすべてのパネルと交換する9つのプログレス・インジケータがあるということです。 私はPlatform.runlaterコマンドとサービスクラスで試してみました。結果は常に同じでした。 ProgressIndicatorは表示されますが、アニメートされません。秒後にすべてのパネルが一度に表示されます。 インジケータが時間の隙間に活気づけられ、次々と交換できる可能性はありますか?JavaFXのバックグラウンドでタスクを実行
9
A
答えて
11
JavaFXにはUIイベントに使用するイベントディスパッチスレッドがあります。 UIのすべての作業はこのスレッドで行われます。 UIの遅れを避けるために、UI以外の計算を行ってはいけません。
は、次のコードを参照してください:
public class Indicators extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
Pane root = new HBox();
stage.setScene(new Scene(root, 300, 100));
for (int i = 0; i < 10; i++) {
final ProgressIndicator pi = new ProgressIndicator(0);
root.getChildren().add(pi);
// separate non-FX thread
new Thread() {
// runnable for that thread
public void run() {
for (int i = 0; i < 20; i++) {
try {
// imitating work
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException ex) {
ex.printStackTrace();
}
final double progress = i*0.05;
// update ProgressIndicator on FX thread
Platform.runLater(new Runnable() {
public void run() {
pi.setProgress(progress);
}
});
}
}
}.start();
}
stage.show();
}
}
12
これは私がこの問題を解決する方法である:
import java.util.Random;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.concurrent.Worker;
import javafx.concurrent.Worker.State;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.TilePane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class Minimal extends Application {
private TilePane loadPane;
private ProgressIndicator[] indicators = new ProgressIndicator[9];
private Label loading[] = new Label[9];
private Color[] colors = {Color.BLACK,Color.BLUE,Color.CRIMSON,Color.DARKCYAN,Color.FORESTGREEN,Color.GOLD,Color.HOTPINK,Color.INDIGO,Color.KHAKI};
private int counter = 0;
@Override
public void start(Stage primaryStage) throws Exception {
//creating Layout
final Group root = new Group();
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.setResizable(false);
StackPane waitingPane = new StackPane();
final ProgressBar progress = new ProgressBar();
Label load = new Label("loading things...");
progress.setTranslateY(-25);
load.setTranslateY(25);
waitingPane.getChildren().addAll(new Rectangle(400,400,Color.WHITE),load,progress);
root.getChildren().add(waitingPane);
//Task for computing the Panels:
Task<Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
for (int i = 0; i < 20; i++) {
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException ex) {
ex.printStackTrace();
}
final double prog = i*0.05;
Platform.runLater(new Runnable() {
public void run() {
progress.setProgress(prog);
}
});
}
return null;
}
};
//stateProperty for Task:
task.stateProperty().addListener(new ChangeListener<Worker.State>() {
@Override
public void changed(ObservableValue<? extends State> observable,
State oldValue, Worker.State newState) {
if(newState==Worker.State.SUCCEEDED){
loadPanels(root);
}
}
});
//start Task
new Thread(task).start();
primaryStage.show();
}
private void loadPanels(Group root) {
//change to loadPanel:
root.getChildren().set(0,createLoadPane());
//Service:
final Service<Rectangle> RecBuilder = new Service<Rectangle>() {
@Override protected Task<Rectangle> createTask() {
return new Task<Rectangle>() {
@Override protected Rectangle call() throws InterruptedException {
updateMessage("loading rectangle . . .");
updateProgress(0, 10);
for (int i = 0; i < 10; i++) {
Thread.sleep(100);
}
updateMessage("Finish!");
return new Rectangle((380)/3,(380)/3,colors[counter]);
}
};
}
};
//StateListener
RecBuilder.stateProperty().addListener(new ChangeListener<Worker.State>() {
@Override public void changed(ObservableValue<? extends Worker.State> observableValue,
Worker.State oldState, Worker.State newState) {
switch (newState) {
case SCHEDULED:
break;
case READY:
case RUNNING:
break;
case SUCCEEDED:
Rectangle rec = RecBuilder.valueProperty().getValue();
indicators[counter].progressProperty().unbind();
loading[counter].textProperty().unbind();
loadPane.getChildren().set(counter, rec);
if(counter<8){
counter++;
nextPane(RecBuilder);
}
break;
case CANCELLED:
case FAILED:
loading[counter].textProperty().unbind();
loading[counter].setText("Failed!");
if(counter<8){
counter++;
nextPane(RecBuilder);
}
break;
}
}
});
//begin PanelBuilding:
nextPane(RecBuilder);
}
private void nextPane(Service<Rectangle> recBuilder) {
loading[counter].textProperty().bind(recBuilder.messageProperty());
indicators[counter].visibleProperty().bind(recBuilder.progressProperty().isNotEqualTo(new SimpleDoubleProperty(ProgressBar.INDETERMINATE_PROGRESS)));
recBuilder.restart();
}
private Node createLoadPane() {
loadPane = new TilePane(5,5);
loadPane.setPrefColumns(3);
loadPane.setPadding(new Insets(5));
for(int i=0;i<9;i++){
StackPane waitingPane = new StackPane();
Rectangle background = new Rectangle((380)/3, (380)/3, Color.WHITE);
indicators[i] = new ProgressIndicator();
indicators[i].setPrefSize(50, 50);
indicators[i].setMaxSize(50, 50);
indicators[i].setTranslateY(-25);
indicators[i].setTranslateX(-10);
loading[i] = new Label();
loading[i].setTranslateY(25);
waitingPane.getChildren().addAll(background,indicators[i],loading[i]);
loadPane.getChildren().add(waitingPane);
}
return loadPane;
}
public static void main(String[] args) {
launch(args);
}
}
+0
ありがとうございます。私は問題は、タスク(より良い単一のタスクインスタンス)が複数回実行できないことだと思います。すべてのメソッド呼び出しでタスクインスタンスを再初期化するメソッドにタスクインスタンスを配置すると、それも私のために解決されました。ニース:) –
関連する問題
- 1. バックグラウンドで長時間実行するタスク
- 2. JavaFX並行性:タスク内でオブジェクトメソッドを実行できますか?
- 3. 複数のオブジェクトでバックグラウンドでタスクを実行しているIOS
- 4. いつもアンドロイドでバックグラウンドでタスクを実行
- 5. アプリケーションが終了した場合のバックグラウンドでのタスクの実行
- 6. バックグラウンドPHPで非常に長いタスクを実行するには?
- 7. タスクをバックグラウンドで実行していますか?
- 8. フォアグラウンドとバックグラウンドで無限にタスクを実行
- 9. バックグラウンドで実行される制御タスクnode.js
- 10. タスクの完了後にJavaFXがコードを実行します
- 11. javafxで継続的に実行されているタスク?
- 12. JavaFX:別のスレッドでタスクを実行しても他のものを実行できない
- 13. バックグラウンドでタスクを実行して、504ゲートウェイのタイムアウトを防ぎます
- 14. バックグラウンドでサービスを実行
- 15. バックグラウンドでジョブを実行
- 16. バックグラウンドでPythonスクリプトを実行
- 17. バックグラウンドでbashスクリプトを実行
- 18. バックグラウンドでPythonスクリプトを実行
- 19. pythonをバックグラウンドで実行
- 20. iOS 10でのバックグラウンド実行
- 21. バックグラウンド実行
- 22. バックグラウンド実行のスケジューリング
- 23. Windows MobileでJavaFXを実行
- 24. アクションからバックグラウンドでSymfonyタスクを正しく実行する方法は?
- 25. バックグラウンドでJavaExecタスクを実行し、ビルドが完了すると終了する
- 26. JavaFx killタスク
- 27. JavaFX並行タスク設定状態
- 28. 別のアプリケーションのバックグラウンドでアプリケーションを実行
- 29. ラズベリーパイのJavafx GUIを実行
- 30. rakeタスクでcapybaraを実行
こんにちはセルゲイ...私は疑問を持って、私は、アプリケーション内で実行されているこれらのスレッドのいくつかを持つことができます?ありがとう。 –
@MarcoR、確かに、 'new Thread()'を何回か実行することができます。 –
Sergeyに感謝します.ApplicationにいくつかのPlatform.runLaterを持つことをお勧めしますか?これらのスレッドはビューを変更する必要があるため、ダイアログを表示するかどうかを検証します。 –