5

各タスクの進行状況とステータスを表示しようとしています。各タスクは への行で表されTableViewます。各タスクは、それぞれで並行して実行されますThread。の画像を参照してくださいTableView

ここに画像の説明を入力

「Progress」については、「ProgressBar」TableColumnをレンダリングするように Cell Factory を設定しました。

  public static class ProgressBarTableCell<S, T> extends TableCell<S, T> {

        private final ProgressBar progressBar;
        private ObservableValue<T> ov;

        public ProgressBarTableCell() {
            this.progressBar = new ProgressBar();
            progressBar.setPrefHeight(23);
            setAlignment(Pos.CENTER);
        }

        @Override
        public void updateItem(T item, boolean empty) {
            super.updateItem(item, empty);
            if (item == null) {
                setGraphic(null);
                setText(null);
            } else {
                if (item.toString().equalsIgnoreCase("Processing")) {
                    Platform.runLater(new Runnable() {
                        @Override
                        public void run() {

                            if (getGraphic() == null) {
                                setGraphic(progressBar);
                                progressBar.setProgress(-1);
                            } else {
                                ProgressBar objpProgressBar = (ProgressBar) getGraphic();
                                objpProgressBar.setProgress(-1);
                            }
                            setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
                        }
                    });
                } else {
                    Platform.runLater(new Runnable() {
                        @Override
                        public void run() {
                            if (getGraphic() == null) {
                                setGraphic(progressBar);
                                progressBar.setProgress(0);
                            } else {
                                ProgressBar objpProgressBar = (ProgressBar) getGraphic();
                                objpProgressBar.setProgress(0);
                            }
                            setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
                        }
                    });
                }
            }
        }
    } 

TableView更新されたステータスとタスクの進行状況が表示されていなかったため、バックグラウンドで定期的にスレッドを実行しています。これは、 startUpdatingTableProgress() を呼び出すと変更され、stopUpdatingTableProgress TableView( )呼び出すと停止します。

 public void stopUpdatingTableProgress() {
    keepUpdating = false;
}

public void startUpdatingTableProgress() {
    keepUpdating = true;
    TableProgressBarUpdator tpu = new TableProgressBarUpdator(table);
    tpu.start();
}

class TableProgressBarUpdator implements Runnable {

    TableView table;

    public TableProgressBarUpdator(TableView fxtable) {
        table = fxtable;

    }

    public void start() {
        new Thread(this).start();
    }

    public void run() {

        while (keepUpdating) {
            try {
                updateProgressbar();
                Thread.sleep(1000);
            } catch (Exception e) {
                LogHandler.doErrorLogging("Error while updating tables cell", e);
            }
        }
        LogHandler.doDebugLogging("Table process repainting is completed.");
    }

    private void updateProgressbar() throws Exception {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                ((TableColumn) table.getColumns().get(0)).setVisible(false);
                ((TableColumn) table.getColumns().get(0)).setVisible(true);
            }
        });


    }
}

しかし今、私JavaFXのアプリのUIは連続してフリーズします。特定の時間間隔の後に自動的にトリガーされ、アプリの UI をフリーズしないバックグラウンド スレッドでupdateProgressbar()を呼び出す別の方法はありますか?JavaFX

各タスクが個別のスレッドで実行されるタスクのステータスを更新する正しい方法であるかどうかはわかりません。の助けを借りてこれを実装したい場合は、javafx.concurrent package誰かがガイダンスやフローを教えてもらえますか? タスクには何が入り、サービス クラスには何が入りますか? プログレスバーを更新するようにスケジュールするにはどうすればよいですか? 参考までに: 一度に並列実行できるスレッドは 5 つだけです。

編集済み -

アンディ氏の提案によると、コードを更新しましたが、まだ運がありません-

TableColumn tableColumn_Progress = new TableColumn("Progress");
        tableColumn_Progress.setCellValueFactory(new PropertyValueFactory<QueueData, Double>("progressBar"));
        tableColumn_Progress.setPrefWidth(100);

        Callback<TableColumn<QueueData, Double>, TableCell<QueueData, Double>> attachmentCellFactory = //
                new Callback<TableColumn<QueueData, Double>, TableCell<QueueData, Double>>() {
            @Override
            public TableCell call(final TableColumn param) {
                final ProgressBarTableCell cell = new ProgressBarTableCell() {
                    @Override
                    public void updateItem(Object item, boolean empty) {
                        super.updateItem(item, empty);
                    }
                };
                return cell;
            }
        };
        tableColumn_Progress.setCellFactory(attachmentCellFactory);

QueueData クラス内 -

DoubleProperty progressBar = null;

public DoubleProperty progressBarProperty() {
        return progressBar;
    }

    public Double getprogressBar() {
        return progressBar.get();
    }

    public void setprogressBar(Double sType) {
        this.progressBar = new SimpleDoubleProperty(sType);
    }

また、バックグラウンド スレッドを呼び出して UI を更新することはありませんが、うまくいきません。

4

2 に答える 2

5

あなたのコードを理解しているので、可視性を反転させて、テーブルセルで updateItem メソッドをトリガーしていますか? これは、任意の数のスレッドが毎秒可視性を変更し、際限なく再描画しようとする可能性があることを意味します。

実装がかなり進んでいることは承知していますが、JavaFX サービス クラスは、更新可能な進捗機能を既に実装しています。これは、現在行っている方法よりもはるかに簡単です。

スレッドから更新するプログレス double プロパティを用意し、これを ProgressBar.progressProperty() にバインドして、すべてが自動的に更新されるようにする方が、はるかに簡単で効率的です。これは Service クラスの仕組みですが、自分で簡単に実装できます。

また、スレッドを破棄していることを確認してください。これは簡単に確認できます。Eclipse でデバッグすると、デバッグ パースペクティブでスレッドのリストが表示されます。無限に大きくならないようにしてください。

Runnable チェックアウトを ScheduledExecutor クラスにスケジュールするには、Executors.newScheduledThreadPool(numOfThreads) を使用して簡単に作成できます。

于 2012-12-12T21:51:35.623 に答える
5

「QueueData」クラスには、既存の進行状況の double プロパティを設定するメソッドが必要です。 setprogressBar(Double sType) メソッドで進行状況を設定するたびに、新しい SimpleDoubleProperty を作成しているようです。

これを次のように更新します -

 public void setprogressBar(Double sType) {
        this.progressBar.set(sType);
    }

開始時に一度progressBarのオブジェクトを作成し、既存のものを更新するだけです。

于 2012-12-14T07:27:43.597 に答える