2016-05-13 6 views
2

私は見てきましたが、正確なプログレスバーを作成する方法を示す適切なスニペットは見つかりませんでした。私が見てきたすべてのものは、Thread.sleep(10)を使って "仕事"を実行するスレッドの作業負荷を示すことで安価にハッキングしています。これは実際にはスレッドのワークロードを考慮しないため、場合によっては非常に不正確です。私はまた、それらが悪く見えるので、不確定なプログレスバーを使用したくありません。JavaFX正確なProgressBarsを作成する

私の質問は、どのようにして数千の画像をディレクトリに書き込む場合に、すべての "仕事"をしているスレッドと並行している正確な進捗バー(不確定ではない)を作成することができますか?あなたがスレッドの作業負荷を知らず、実際にそれらのすべてをダンプするのにどれくらい時間がかかるかわからない場合。これにアプローチする最善の方法は何ですか?私はこれを現実的にして、化粧品のためだけに進行状況バーを表示しないようにしています。

私はこのようなプログラムを持っているとしましょう。

 @FXML 
    private void dump(ActionEvent e) { 
     try { 
       if (e.getSource() == spriteDumpMI) { 

        Thread thread = new Thread(() -> { 

          try (Cache cache = new Cache(FileStore.open(Constants.CACHE_PATH))) { 
           ReferenceTable table = ReferenceTable.decode(Container 
              .decode(cache.getStore().read(255, 8)).getData()); 

           Platform.runLater(() -> { 
             createTask(10, table.capacity()); 
           }); 


           for (int i = 0; i < table.capacity(); i++) { 
             if (table.getEntry(i) == null) 
              continue; 

             Container container = cache.read(8, i); 
             Sprite sprite = Sprite.decode(container.getData()); 

             File dir = new File(Constants.SPRITE_PATH); 

             if (!dir.exists()) { 
              dir.mkdir(); 
             } 

             for (int frame = 0; frame < sprite.size(); frame++) { 
              File file = new File(Constants.SPRITE_PATH, 
                 i + "_" + frame + ".png"); 
              BufferedImage image = sprite.getFrame(frame); 

              ImageIO.write(image, "png", file); 
             } 

           } 
          } catch (FileNotFoundException e1) { 
           e1.printStackTrace(); 
          } catch (IOException e1) { 
           e1.printStackTrace(); 
          } 

        }); 

        thread.start(); 

       } 
     } catch (Exception ex) { 
       ex.printStackTrace(); 
     } 
    } 

プログラムは単純ですが、基本的には、アーカイブに発見されたスプライトのすべてを書き込む(数千のイメージすることができます)と、ユーザーがそれらを使用できるようにディレクトリにそれらのすべてを書き込みます。

これを使用して進行状況バーを更新しています。

        Platform.runLater(() -> { 
             // this is bad 
             createTask(10, table.capacity()); 
           }); 

は私がループでプログレスバーを更新する可能性が理解し、私は(も本当に悪いです)スレッドと新しいタスクのトンを作成せずにそれを行う方法がわからないんだけど

そして、メソッドcreateTask

 private void createTask(int workload, int max) { 

     Task<Boolean> task = taskCreator(workload, max); 

     progressBar.setVisible(true); 
     progressI.setVisible(true); 

     progressBar.progressProperty().unbind(); 
     progressBar.progressProperty().bind(task.progressProperty()); 

     progressI.progressProperty().unbind(); 
     progressI.progressProperty().bind(task.progressProperty()); 

     new Thread(task).start(); 
    } 

    private Task<Boolean> taskCreator(int workload, int max) { 
     return new Task<Boolean>() { 

       @Override 
       protected Boolean call() throws Exception { 

        progressText.setText("In Progress"); 
        progressText.setFill(Color.WHITE); 

        for (int index = 0; index < max; index++) { 
          Thread.sleep(workload); 

          updateProgress(index, max); 
        } 

        progressText.setText("Complete!"); 
        progressText.setFill(Color.GREEN); 

        Thread.sleep(1000); 

        progressBar.setVisible(false); 
        progressI.setVisible(false); 
        progressText.setText(""); 

        return true; 

       } 

     }; 
    } 

答えて

0

これは役に立ちます。

@FXML 
private void dump(ActionEvent e) { 

    try { 
      if (e.getSource() == spriteDumpMI) { 

       progressBar.setVisible(true); 
       progressI.setVisible(true); 

       progressBar.progressProperty().unbind(); 
       progressBar.progressProperty().bind(task.progressProperty()); 

       progressI.progressProperty().unbind(); 
       progressI.progressProperty().bind(task.progressProperty()); 

       progressText.textProperty().unbind(); 
       progressText.textProperty().bind(task.messageProperty()); 
       progressText.setFill(Color.GREEN); 

       Task task = new Task<Boolean>() { 

        @Override 
        protected Boolean call() throws Exception { 
         updateMessage("In Progress"); 

         try (Cache cache = new Cache(FileStore.open(Constants.CACHE_PATH))) { 
           ReferenceTable table = ReferenceTable.decode(Container 
              .decode(cache.getStore().read(255, 8)).getData()); 
           long count; 
           for (int i = 0; i < table.capacity(); i++) { 
             if (table.getEntry(i) == null) 
              continue; 

             Container container = cache.read(8, i); 
             Sprite sprite = Sprite.decode(container.getData()); 

             File dir = new File(Constants.SPRITE_PATH); 

             if (!dir.exists()) { 
              dir.mkdir(); 
             } 

             for (int frame = 0; frame < sprite.size(); frame++) { 
              count++; 
             } 

           } 

           int current; 
           for (int i = 0; i < table.capacity(); i++) { 
             if (table.getEntry(i) == null) 
              continue; 

             Container container = cache.read(8, i); 
             Sprite sprite = Sprite.decode(container.getData()); 

             File dir = new File(Constants.SPRITE_PATH); 

             if (!dir.exists()) { 
              dir.mkdir(); 
             } 

             for (int frame = 0; frame < sprite.size(); frame++) { 
              File file = new File(Constants.SPRITE_PATH, 
                 i + "_" + frame + ".png"); 
              BufferedImage image = sprite.getFrame(frame); 

              ImageIO.write(image, "png", file); 
              current++; 
              updateProgress(current, count); 
             } 

           } 
           updateMessage("Complete!"); 
           Platform.runLater(() -> { 
            progressText.setFill(Color.GREEN); 
           }); 
          } catch (FileNotFoundException e1) { 
           e1.printStackTrace(); 
           updateMessage("failed!"); 
           Platform.runLater(() -> { 
            progressText.setFill(Color.GREEN); 
           }); 
          } catch (IOException e1) { 
           e1.printStackTrace(); 
           updateMessage("failed!"); 
           Platform.runLater(() -> { 
            progressText.setFill(Color.GREEN); 
           }); 
          } 
         return true; 

         } 

       }; 

      } 
      task.setOnSucceeded(e ->{ 
       progressBar.setVisible(false); 
       progressI.setVisible(false); 
       progressText.setText(""); 
      }); 
      task.setOnFailed(e ->{ 
       progressBar.setVisible(false); 
       progressI.setVisible(false); 
       progressText.setText(""); 
      }); 

      new Thread(task).start(); 
    } catch (Exception ex) { 
      ex.printStackTrace(); 
    } 

}

+0

はええ、それはあなたが作成したタスクインスタンスのスコープで見て、どこがアクセスしようとしている、働くつもりはありません。しかし、私は試していただければ幸いです –

+0

どのようなタスクの範囲がある必要がありますか? – Rhain

+0

"task"インスタンスの上にあるときに 'task.progressProperty()'を取得しようとしています。私はそれを理解したと思う、秒以内に病気。 –

関連する問題