JavaFX - 在动态加载的Gridpane上使用Progressbar

时间:2014-06-02 21:50:39

标签: javafx

我正在使用GridPane,我将数据从数据库加载到窗格,动态创建行和列。它工作正常,但有时候,如果有很多东西(大约30行和30列,并且每个单元格都有一个EventListener)要加载,看到加载的东西需要一秒多的时间。

所以,我想,添加ProgressBar或ProgressIndicator会很棒。我试过了,但是我意识到它并不依赖于循环,这些循环正在填充和创建动态GridPane,但事实上"加载和应用"花了很多时间。我的ProgressIndicator从0跳到100,这不是我想要的。

您是否有一些想法如何解决这个问题?我阅读了一些关于预加载器的文章,我正在寻找类似的功能,但我无法使用Preloaders来解决这个问题。

致以最诚挚的问候,

编辑:现在我找到了一个有效的解决方案,但我不认为别人会写这样的代码:S。 我创建了一个名为LoaderDienstplan的类:

public class LoaderDienstplan extends Task {
    //Some member variables for starting call() method

    @Override
    protected Object[] call() throws Exception{
        // calling DB and service
        updateProgress(1,1);
        return; // Returning an ObjectArray with Lists,Data and a reference to my  Controllerclass
    }
    @Override
    public void run(){
        final Object[] b = call();
        Platform.runLater(new Runnable(){
        @Override
        public void run(){
            //Updating GridPane
            }
        });
    }
}

1 个答案:

答案 0 :(得分:0)

public class LoaderDienstplan extends Task {

MyInterface listener;
//Some member variables for starting call() method

@Override
protected Object[] call() throws Exception{
    // calling DB and service
    updateProgress(1,1);
    return; // Returning an ObjectArray with Lists,Data and a reference to my  Controllerclass
}

public void setListener(MyInterface listener) {
    this.listener = listener;
}

@Override
public void run() {
    final Object[] b = call();
    Platform.runLater(new Runnable(){
    @Override
    public void run() {
        //Updating GridPane
             listener.updateGUI(something);
        }
    });
}
}

界面:

public interface MyInterface {
     void updateGUI(Something something);
     void loadingFinished();
}

从您的Controller类中,必须 implements MyInterface

LoaderDienstplan load = new LoaderDienstplan(...);
load.setListener(this);

上课:

public class Loader implements Runnable {

   private final MyController listener;
   private final List<File> stuff;
   public DoubleProperty progressProperty;

   public Loader(MyController listener, List<File> stuffToLoad) {
     this.stuff = stuffToLoad;
     progressProperty = new SimpleDoubleProperty();
     this.listener = listener;
   }

   private void updateProgress(double value, double max) {
     progressProperty.set(value / max);
   }

   public DoubleProperty progressProperty() {
      return progressProperty;
   }

   @Override
   public void run() { 
      Platform.runLater(new Runnable() {
          public void run() {
             //load the stuffs
          }
      });
      //each time you load another stuff, do:
      updateProgress(index, totalAmountOfStuffs);

      //when finished, do:
      listener.finished();
   }
}

在GridPane周围放一个面纱和一个指示器,就像这样(我在JavaFX SceneBuilder中制作面纱(Region)和指示器(ProgressIndicator)):

//lets say your progress indicator is called progressIndicator and the shaded `Region` is called veil
progressIndicator.setMaxSize(150, 150);
veil.setStyle("-fx-background-color: rgba(0, 0, 0, 0.4)");

从另一个线程运行Loader类:

private void startLoading() {
   progressIndicator.setVisible(true);
   veil.setVisible(true);
   Loader loader = new Loader(this, stuffToLoad);
   progressIndicator.progressProperty().bind(loader.progressProperty());
   new Thread(loader).start();
}

@Override
public void finished() {
   progressIndicator.setVisible(false);
   veil.setVisible(false);
}

对我来说是什么样的: enter image description here