JavaFX TableView performance issue

2019-04-06 18:55发布

I am using javafx table view control to display my table data. Now the data is quite huge and when I show the full data in the control it crashes. Is there any way to do so or will I have to cache the data so that I can display it in chunks. Should I use JTable instead ?

2条回答
手持菜刀,她持情操
2楼-- · 2019-04-06 19:10

I'm not quite sure if I understand your question right, but what about lazy loading of the items? Actually there is an example within the Docs directly. Though it is for the TreeView and not for the TableView, you should be able to simply adapt the idea behind.

Hope that helps, at least for my TreeView, it solved a lot of problems so far.

Cheers, Regine

查看更多
萌系小妹纸
3楼-- · 2019-04-06 19:30

I made a lazy-load on tableview using the CellFactory class... I´ll try to explain, anyone with better english than mine fell free to edit and make it more understandable!

First I use a mandatory property in a Bean to check if that bean has already been loaded or not. This way I don't need to create an attribute specifically for that.

Second, I loaded into TableView my Bean collection just with the 'id' property loaded, what makes my table display all in blank.

At last, I create a CellFactory, like this one below, to check if object has loaded or not, and if not do it now.

namecolumn.setCellFactory(new Callback<TableColumn<PersonBean, String>, TableCell<PersonBean, String>>() {
@Override
  public TableCell<PersonBean, String> call(TableColumn<PersonBean, String> param) {
    TableCell<PersonBean, String> newtablecell = new TableCell<PersonBean, String>() {
      @Override
      protected void updateItem(String item, boolean empty) {
        // Since I got some strange errors when method getIndex() return greatter value than my collection size, I need to validate before getting the object
        if (getIndex() < getItems().size()) {
          //Retrieve the collection object
          PersonBean personbean = getItems().get(getIndex());
          // Name is mandatory, so if it is null my bean was not loaded yet
          if (personbean.getName() == null) {
            // Call other centralized method to make load, details explained later
            loadPersonBean(personbean);
          }
          // Now I put the value on TableCell. Remember "item" still empty so we need to use Bean
          setText(personbean.getName());
          setAlignment(Pos.CENTER);
        }
      }
    };
    return newtablecell;
  }
});

In the method loadPersonBean I pass the object contained in TableView Collection and load it from DataBase. Than I COPY all the needed data to the bean received from the table. I didn't try to swap the object in TableView, but I believe it may result a Concurrent Exception.

Other observation: In all my tests TableView always respects the column order to call my CellFactory, but I did not test if it still respects the order if user swap the column order. So I prefer to add a CellFactory with the "LazyLoadCheck" part of code to all columns.

Hope I made my self clear enough to help! If any questions remains, comment and I'll try to do a better explanation.

查看更多
登录 后发表回答