2016-10-14 7 views
0

別の画像がロードされているときに、ピクチャビューアの進捗値を取得しようとしています。私はそれを行うには2つの簡単な方法を試みたが、それは私のためにうまくいかなかった。JavaFX - 進行状況のプロパティが機能しません。

まず私はImageクラスからprogressPropertyを使用していた。

public boolean nextImageClicked() 
{ 
    if(PICTURE_INDEX < picturePaths.size() - 1) 
    { 
     String path = picturePaths.get(PICTURE_INDEX + 1).toURI().toString(); 
     Image newImage = new Image(path); 
     newImage.progressProperty().addListener((observable, oldValue, newValue) -> System.out.println("Current progress: "+newValue)); 
     GUI.getImageView().setImage(newImage); 
     adjustImageViewBounds(); 
     PICTURE_INDEX += 1; 
     return true; 
    } 
    else return false; 
} 

進捗値が異様に変更されないので、コンソールに何も出力しませんでした。だから私はTask<Void>ですべての作業のものを入れてみましたとTaskを通じて進捗値を取得しました。期待して

public boolean nextClicked() 
{ 
    if(PICTURE_INDEX < picturePaths.size() - 1) 
    { 
     Task<Void> task = new Task<Void>() 
     { 
      @Override protected Void call() throws Exception 
      { 
       String path = picturePaths.get(PICTURE_INDEX + 1).toURI().toString(); 
       Image newImage = new Image(path); 
       GUI.getImageView().setImage(newImage); 
       adjustImageViewBounds(); 
       PICTURE_INDEX += 1; 
       return null; 
      } 
     }; 
     task.setOnRunning(e -> System.out.println(task.getProgress())); 
     task.progressProperty().addListener((observable, oldValue, newValue) -> 
     { 
      System.out.println(newValue); 
     }); 
     task.run(); 
     return true; 
    } 
    else return false; 
} 

もうまくいきませんでした。

task.setOnRunning(e -> System.out.println(task.getProgress())); 

これを実装してデフォルト値を確認したところ、 "-1"が出力されました。

コンソールに「0.1」、「0.14」などの単一の進捗値が返さ​​れるように変更するにはどうすればよいですか?

+0

'Image'の' backgroundLoading'フラグのデフォルト値は文書化されていませんが、 'false'と信じています。したがって、指定しない場合、 'Image'コンストラクタは画像がロードされるまでブロックします。その結果、リスナーを登録した後では、 'progress'プロパティは変更されません(ロードはすでにその時点で完了しています)。背景の読み込みを 'true'に設定してみてください。それでも、イメージがすばやく読み込まれると、出力は表示されません。 –

+0

タスクバージョンでは、タスクの進捗プロパティを更新することはありません。そのため、値の変更が表示される理由はありません。 –

+0

コンストラクタを使ってbackgroundLoadingプロパティをtrueに変更しました。仕事は何ですか?どうすればそれを入手できますか?答えとして投稿してください。私はそれを参考にしてマークすることができます。 – Rouman

答えて

1

画像の前にコンストラクタが返すへの呼び出しが完全にロードされるようにするには、バックグラウンドでロードするようにImageを必要としています。デフォルトでは、それがロードされるまで(その進捗プロパティは、あなたがそれにリスナーを追加し、時間によって1になります)ブロックします:

public boolean nextImageClicked() 
{ 
    if(PICTURE_INDEX < picturePaths.size() - 1) 
    { 
     String path = picturePaths.get(PICTURE_INDEX + 1).toURI().toString(); 

     // note additional parameter: 
     Image newImage = new Image(path, true); 

     newImage.progressProperty().addListener((observable, oldValue, newValue) -> System.out.println("Current progress: "+newValue)); 
     GUI.getImageView().setImage(newImage); 
     adjustImageViewBounds(); 
     PICTURE_INDEX += 1; 
     return true; 
    } 
    else return false; 
} 

Taskの進捗状況が変化するためには、明示的に呼び出す必要がありますタスクのupdateProgress(...)何を渡すべきかを知る唯一の方法は、画像の進捗状況を観察し、それをタスクの進捗状況に渡すことです。そのため、上のコードをもっと複雑なものにするだけです。 Imageは既にボックスのバックグラウンド読み込みをサポートしているので、これはタスクの良いユースケースではありません。

+0

すばらしい説明、ありがとう! – Rouman

1

あなた自身でこれを行おうとしないでください。ロードの前にイメージのサイズを見つけてストリームの進行状況を監視する蒸気からイメージをロードするまで、イメージがどれだけロードされたか分かりません。これは不必要に複雑になります。ところで、あなたが使用するコンストラクタImageは、イメージが完全に読み込まれたときに戻ります。ただし、非同期にロードするイメージはby using the right constructorと指定できます。 Imageは、ロードの進行状況を観察するprogressプロパティを提供します。

@Override 
public void start(Stage primaryStage) { 
    ImageView iv = new ImageView(); 
    ProgressBar pb = new ProgressBar(); 
    Button btn = new Button("Load Image"); 
    btn.setOnAction((ActionEvent event) -> { 
     // ca. 6 MB image loaded from web 
     Image image = new Image("http://eoimages.gsfc.nasa.gov/images/imagerecords/79000/79793/city_lights_africa_8k.jpg", true); 
     pb.progressProperty().bind(image.progressProperty()); 
     iv.setImage(image); 
    }); 

    ScrollPane sp = new ScrollPane(iv); 
    VBox.setVgrow(sp, Priority.ALWAYS); 
    VBox root = new VBox(btn, pb, sp); 
    root.setFillWidth(true); 

    Scene scene = new Scene(root); 
    primaryStage.setMaximized(true); 

    primaryStage.setScene(scene); 
    primaryStage.show(); 
} 
関連する問題