1

私は javafx tableview に取り組んでおり、100,000 行 (3 列 1 int 2 float) のテーブルを作成しました。

アクティブな並べ替えをオンにしています。新しい行を挿入するには、最初にバイナリ検索を使用してインデックスを検索し、次に table.getItems.add(index,element); を使用して挿入します。

しかし、20 ミリ秒ごとに新しい行が追加されると、GUI は少し反応しなくなります。

table.setSelectionModel(null);を追加しました。そしてそれは私のGUIを固定するので、遅いGUIの背後にあるようです.

しかし、行を選択する機能も必要です.....

誰もがこの場合に何をすべきかを提案します....

PS :( table.setSelectionModel(null);行を追加する前に、 jprofiler を実行しようとしましたが、 javafx.scene.control.TableCell$2.onChangedで多くの時間が消費されていることが示されていました)

編集:

私のユースケース

import java.util.ArrayList;  
import java.util.Collections;  
import java.util.Comparator;  
import java.util.List;  
import java.util.Random;  
import javafx.animation.Animation;  
import javafx.animation.KeyFrame;  
import javafx.animation.Timeline;  
import javafx.application.Application;  
import javafx.beans.binding.Bindings;  
import javafx.beans.property.SimpleStringProperty;  
import javafx.beans.property.StringProperty;  
import javafx.collections.FXCollections;  
import javafx.collections.ObservableList;  
import javafx.event.ActionEvent;  
import javafx.event.EventHandler;  
import javafx.geometry.HPos;  
import javafx.scene.Scene;  
import javafx.scene.control.Button;  
import javafx.scene.control.Label;  
import javafx.scene.control.SelectionMode;  
import javafx.scene.control.TableColumn;  
import javafx.scene.control.TableColumn.SortType;  
import javafx.scene.control.TableView;  
import javafx.scene.control.TextField;  
import javafx.scene.control.cell.PropertyValueFactory;  
import javafx.scene.layout.BorderPane;  
import javafx.scene.layout.ColumnConstraints;  
import javafx.scene.layout.GridPane;  
import javafx.stage.Stage;  
import javafx.util.Duration;  
public class TableInsertExample extends Application {  
  int count=0;  
    long s,e,mx=0,mn=1000000000;  
    float avg=0;  
  private static final Random RNG = new Random();  
  private Comparator<Person> tableOrderComparator ;  
  @SuppressWarnings("unchecked")  
@Override  
  public void start(Stage primaryStage) {  
    final BorderPane root = new BorderPane();  
    final TableView<Person> table = new TableView<Person>();  
    table.setItems(createData());  
    final TableColumn<Person, String> firstNameColumn = new TableColumn<Person,String>("First Name");  
    final TableColumn<Person, String> lastNameColumn = new TableColumn<Person,String>("Last Name");  
    firstNameColumn.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName"));  
    lastNameColumn.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName"));  
    table.getColumns().addAll(firstNameColumn, lastNameColumn);  

    tableOrderComparator = createTableOrderComparator(table);  

   //this line increase speed but then we can not even click on table as it will give someexception  
    table.setSelectionModel(null);  


    final GridPane addPersonPane = new GridPane();  
    final TextField firstNameTF = new TextField();  
    final TextField lastNameTF = new TextField();  
    final Button addButton = new Button("Add");  
    addPersonPane.addRow(0, new Label("First Name:"), firstNameTF);  
    addPersonPane.addRow(1, new Label("Last Name:"), lastNameTF);  
    addPersonPane.addRow(2, addButton);  
    final ColumnConstraints leftColConstraints = new ColumnConstraints();  
    leftColConstraints.setHalignment(HPos.RIGHT);  
    final ColumnConstraints rightColConstraints = new ColumnConstraints();  
    rightColConstraints.setHalignment(HPos.LEFT);  
    addPersonPane.getColumnConstraints().addAll(leftColConstraints, rightColConstraints);  

    addButton.setOnAction(new EventHandler<ActionEvent>() {  

      @Override  
      public void handle(ActionEvent event) {  
        final Person person = new Person(firstNameTF.getText(), lastNameTF.getText());  
        addPersonToTable(table, person);  
      }  
    });  
     table.getSortOrder().addAll(firstNameColumn);  
    Label countLabel = new Label();  
    countLabel.textProperty().bind(Bindings.format("Table has %s entries", Bindings.size(table.getItems())));  
    root.setTop(countLabel);  
    root.setCenter(table);  
    root.setBottom(addPersonPane);  
    primaryStage.setScene(new Scene(root, 400, 600));  
    primaryStage.show();     

    Timeline addRandomPeopleFrequently = new Timeline(new KeyFrame(Duration.millis(20), new EventHandler<ActionEvent>() {  
      @Override  
      public void handle(ActionEvent event) {  
        Person randomPerson = new Person(randomString(), randomString());  
        count++;  
        addPersonToTable(table, randomPerson);  
      }  
    }));  
    addRandomPeopleFrequently.setCycleCount(Animation.INDEFINITE);  
    addRandomPeopleFrequently.play();  
  }  
  private Comparator<Person> createTableOrderComparator(  
      final TableView<Person> table) {  
    return new Comparator<Person>() {  
      @Override  
      public int compare(Person person1, Person person2) {  
        for (TableColumn<Person, ?> col : table.getSortOrder()) {  
          Comparator colComp = col.getComparator();  
          if (colComp == null) {  
            colComp = TableColumn.DEFAULT_COMPARATOR;  
          }  
          final Object o1 = col.getCellData(person1);  
          final Object o2 = col.getCellData(person2);  
          int c = colComp.compare(o1, o2);  
          if (col.getSortType() == SortType.DESCENDING) {  
            c = -c ;  
          }  
          if (c != 0) {  
            return c;  
          }  
        }  
        return 0 ;  
      }  
    };  
  }  
  public static void main(String[] args) {  
    launch(args);  
  }  
  private ObservableList<Person> createData() {  
    List<Person> list = new ArrayList<Person>();  
    for (int i=0; i<100000; i++) {  
      list.add(new Person(randomString(), randomString()));  
    }  
    return FXCollections.observableList(list);  
  }  
  private String randomString() {  
    StringBuilder sb = new StringBuilder();  
    for (int i=0; i<8; i++) {  
      sb.append((char)(RNG.nextInt(26)+'a'));  
    }  
    return sb.toString();  
  }  
  private void addPersonToTable(final TableView<Person> table,  
       final Person person) {  
     int index ;  
     final ObservableList<TableColumn<Person, ?>> tableSortOrder = table.getSortOrder();  
     if (tableSortOrder.size()==0) {  
       index = table.getItems().size();  
     } else {  
       index = Collections.binarySearch(table.getItems(), person, tableOrderComparator);  
       if (index < 0) {  
         index = -index-1 ;  
       }  
     }  
     s=System.currentTimeMillis();  
     List<Person> leftList = table.getItems().subList(0, index);  
     List<Person> rightList = table.getItems().subList(index, table.getItems().size());  
     List<Person> newList = new ArrayList<Person>(table.getItems().size()+1);  
     newList.addAll(leftList);  
     newList.add(person);  
     newList.addAll(rightList);  
   /*  int selectedIndex = table.getSelectionModel().getSelectedIndex(); 
     if (index < selectedIndex) { 
       selectedIndex++; 
     }  */  
     table.getItems().setAll(newList);  
    // table.getSelectionModel().select(selectedIndex);  
     e= System.currentTimeMillis() - s;  
  avg+=e;  
  if(mx<e)  
  mx=e;  
  if(mn>e)  
  mn=e;  
  if(count==1000)  
  {  
  avg=avg/10000;  
  System.out.format("current System time is %f. Max is %d . Min is %d%n",avg,mx,mn);  
  count=0;  
  avg=0;  
  mx=0;  
  mn=100000000;  
  }  
   }  
  public static class Person {  
    private final StringProperty firstName ;  
    private final StringProperty lastName ;  
    Person(String firstName, String lastName) {  
      this.firstName = new SimpleStringProperty(this, "firstName", firstName);  
      this.lastName = new SimpleStringProperty(this, "lastName", lastName);  
    }  
    public String getFirstName() { return firstName.get(); }  
    public void setFirstName(String firstName) { this.firstName.set(firstName);}  
    public StringProperty firstNameProperty() { return firstName ; }  
    public String getLastName() { return lastName.get(); }  
    public void setLastName(String lastName) { this.lastName.set(lastName); }  
    public StringProperty lastNameProperty() { return lastName ; }     
    @Override public String toString() { return firstName.get() + " " + lastName.get() ; }  

  }  
}  

この行の先頭

//this line increase speed but then we can not even click on table as it will give someexception  
    table.setSelectionModel(null);

挿入速度を平均0.2 ミリ秒に上げるのに役立ちます(平均を計算するためのコードはコードに含まれています)

ただし、選択を無効にします(この理由により、 addPersonToTableのコードはコメント化されています)

行を選択する機能が必要ですが、このコードの速度効率はいくらかです。(私は Jprofiler を使用しましたが、主な時間がTableCell.onChangedに費やされていることを示しています)

注:このコードは James_D によって書かれました。少し修正しただけです (addPersonToTable に行 table.setSelectionModel(null); とコメント行を追加)。

4

1 に答える 1