ファイルサイズが数千から数百万行になる大容量ファイルを1行ずつ解析しています。ファイルが少ない場合(例えば、10,000行が少ない場合)、すべてのコンポーネント(下の画像で赤い矢印で示されたコンポーネント)がすぐに1行ずつ更新され、プロセスがどこにあるのかを正確に示します。ファイルが大きい場合、更新に大きな遅延があり、インジケータが進捗状況を反映するまでに最大30秒かかることがあります。私はディスプレイをリフレッシュするためにそれを手動でサイズ変更することができました。Javafxの進捗状況が十分に速く更新されない
行毎にファイルがupdateProgress()
ですが、ストリーミング時に呼び出されるメソッド。そこにはprogressPrevVal
が0から1になり(それぞれの増分は1.0/2,675,150
)、lineNum
は、この例を画像で使用すると1から2,675,150になります。 、
Runnable task =() -> {
DxProgressIndicator.main(null);
};
Thread thread = new Thread(task);
thread.start();
私は、ファイルを介して行くことができます:私はこのような独自のスレッドでGUIを起動したら、
import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
public class DxProgressIndicator extends Application {
private static ProgressBar pb;
private static ProgressIndicator pi;
private static TextField tfNumbers;
private static Label lblLineNumVal;
private static Label lblAllLines;
private static double progressIncrement;
private static double progressPrevVal;
private static int lineNum;
private static Label lblFile;
@Override
public void start(Stage stage) {
Group root = new Group();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setTitle("Dexter Parser");
lblFile = new Label();
final HBox hbFile = new HBox();
hbFile.setAlignment(Pos.CENTER_LEFT);
Label lblCurrentFile = new Label("Current file: ");
lblCurrentFile.setMinWidth(90);
lblCurrentFile.setFont(Font.font(null, FontWeight.BOLD, 13));
hbFile.getChildren().addAll(lblCurrentFile, lblFile);
pb = new ProgressBar(0);
pb.setMinWidth(450);
pi = new ProgressIndicator(0);
final HBox hbPis = new HBox(10);
hbPis.setAlignment(Pos.CENTER_LEFT);
hbPis.getChildren().addAll(pb, pi);
lblLineNumVal = new Label();
lblLineNumVal.setMaxWidth(200);
Label slash = new Label("/");
lblAllLines = new Label();
final HBox hbLines = new HBox();
hbLines.setAlignment(Pos.CENTER_LEFT);
Label lblLineNum = new Label(" Currently parsing Line # : ");
lblLineNum.setFont(Font.font(null, FontWeight.BOLD, 12));
hbLines.getChildren().addAll(lblLineNum, lblLineNumVal, slash, lblAllLines);
tfNumbers = new TextField();
tfNumbers.setEditable(false);
tfNumbers.setMaxWidth(100);
final HBox hbTrxValues = new HBox();
hbTrxValues.setAlignment(Pos.CENTER_LEFT);
Label lblNumbers = new Label("(transaction, step, record) = ");
lblNumbers.setFont(Font.font(null, FontWeight.BOLD, 12));
hbTrxValues.getChildren().addAll(lblNumbers, tfNumbers);
final VBox vb = new VBox(10);
vb.getChildren().addAll(hbFile, hbPis, hbLines, hbTrxValues);
vb.setPadding(new Insets(10));
scene.setRoot(vb);
stage.show();
}
public static void updateProgress() {
Platform.runLater(() -> {
progressPrevVal += progressIncrement;
pb.setProgress(progressPrevVal);
pi.setProgress(progressPrevVal);
lblLineNumVal.setText(Integer.toString(lineNum++));
});
}
public static void setFileMetadata(String str) {
Platform.runLater(() -> {
lblAllLines.setText(str);
progressIncrement = 1/Double.valueOf(str);
progressPrevVal = 0d;
lineNum = 1;
});
}
public static void main(String[] args) {
launch(args);
}
}
クライアントのmainメソッドから:ここで
は、全体のコードです
try (Stream<String> stream = Files.lines(file)) {
stream.forEach(line -> {
DxProgressIndicator.updateProgress();
// a bunch of stuff to do with the line
});
} catch (IOException e) {
}
私は何が欠けていますか?非常に大きなファイルを処理する場合、コンポーネントを1分ごとに更新するのではなく、繰り返しごとにスムーズに更新できるように、更新を強制するにはどうすればよいですか?
ありがとうございます。
FXアプリケーションスレッドには、それほど多くの更新情報が氾濫している可能性があります。 JavaFX ['Task'](http://docs.oracle.com/javase/8/javafx/api/javafx/concurrent/Task.html)を使用して、インジケータの進行状況プロパティをタスクのprogressプロパティにバインドし、 'updateProgress()'を呼び出すと、更新の数が制限されます。 (実際の答えを提供するためにあなたのコードを解くことができない理由)UIクラスの外からこれを運転する理由は明らかではありません。通常は、 'start ) 'メソッドを呼び出します。 –
2つ目は、ファイルを1行ずつ順番に処理する多くのプロジェクトを構築する必要がありますが、最終的にはさまざまなことを行うことになります。このようにして、私はここで同じアプリケーション(つまり 'updateProgress()'メソッド)を使用して、ファイルをストリームするプロジェクトを扱うことができます。 – mohsenmadi
しかし、同じUI構造を再利用する明確な方法があります。人為的にすべてを静的にする必要はありません。たとえば、このアプローチでは、これらの2つを一度に開くことができなくなります。後で簡単に問題になると思います。 –