javafx tableview仅在排序后更新数据

时间:2013-06-11 16:27:07

标签: java javafx tableview

我有两个javafx表视图。如果我更改了第一个中的值,则第二个值仅在排序后显示更改(尽管模型已更新)。

我的实体

package Entity;

import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;

public class Arbeitgeber {

private SimpleIntegerProperty id = new SimpleIntegerProperty();
private SimpleStringProperty name = new SimpleStringProperty();

public int getId() {
    return id.get();
}

public void setId(int id) {
    this.id.set(id);
}
...


package Entity;

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;

public class Person {

private SimpleIntegerProperty id = new SimpleIntegerProperty();
private SimpleStringProperty name = new SimpleStringProperty();
private SimpleStringProperty gruppe = new SimpleStringProperty();
private ObjectProperty<Arbeitgeber> arbeitgeber = new SimpleObjectProperty<>();

public int getId() {
    return id.get();
}

public void setId(int id) {
    this.id.set(id);
}
...

我的测试用例

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import Entity.Arbeitgeber;
import Entity.Person;


public class TableviewTest extends Application {

private TableView<Arbeitgeber> arbeitgeberTable;
private TableView<Person> personTable;

ObservableList<String> gruppeOptions = 
    FXCollections.observableArrayList(
        "Arbeiter",
        "Angestellter",
        "Leiter"
    );

private ObservableList<Arbeitgeber> arbeitgeberListe = FXCollections.observableArrayList(new Arbeitgeber(1, "Goldgräber Inc."), new Arbeitgeber(2, "Hamster GmbH"), new Arbeitgeber(3, "Wissen"));
private ObservableList<Person> personen = FXCollections.observableArrayList(
        new Person(1, "Max Musterman", gruppeOptions.get(1), arbeitgeberListe.get(0)), 
        new Person(2, "Bernd Brot", gruppeOptions.get(0), arbeitgeberListe.get(0)), 
        new Person(3, "Fred Feuer", gruppeOptions.get(2), arbeitgeberListe.get(1)), 
        new Person(4, "Uli Stein", gruppeOptions.get(1), arbeitgeberListe.get(2)));

@Override
public void start(Stage primaryStage) throws Exception {
    createArbeitgeberTableview();
    createPersonTableview();

    VBox vbox = new VBox(15);

    Label aLabel = new Label("Arbeitgeber");
    Label pLabel = new Label("Personen");
    vbox.getChildren().addAll(aLabel, arbeitgeberTable, pLabel, personTable);

    Scene scene = new Scene(vbox);
    primaryStage.setScene(scene);

    primaryStage.show();
}

/**
 * @param args
 */
public static void main(String[] args) {
    launch(args);
}

@SuppressWarnings({ "unchecked", "rawtypes" })
private TableView<Arbeitgeber> createArbeitgeberTableview() {
    arbeitgeberTable = new TableView<>(arbeitgeberListe);

    arbeitgeberTable.setEditable(true);

    TableColumn<Arbeitgeber, Integer> idCol = new TableColumn<>("ID");
    TableColumn nameCol = new TableColumn<>("Name");

    idCol.setCellValueFactory(new PropertyValueFactory<Arbeitgeber, Integer>("id"));
    nameCol.setCellValueFactory(new PropertyValueFactory<Arbeitgeber, String>("name"));


    nameCol.setCellFactory(TextFieldTableCell.forTableColumn());
    nameCol.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<Arbeitgeber,String>>() {

        @Override
        public void handle(CellEditEvent<Arbeitgeber, String> event) {
            ((Arbeitgeber) event.getTableView().getItems().get(event.getTablePosition().getRow())).setName(event.getNewValue());                

            for(Person p : personTable.getItems()) {    
                System.out.println(p.getArbeitgeber()); //shows the new value
            }
        }
    });

    arbeitgeberTable.getColumns().addAll(idCol, nameCol);
    arbeitgeberTable.setTableMenuButtonVisible(true);
    return arbeitgeberTable;
}

@SuppressWarnings("unchecked")
private TableView<Person> createPersonTableview(){
    personTable = new TableView<>(personen);

    TableColumn<Person, Integer> idCol = new TableColumn<>("ID");
    TableColumn<Person, String> nameCol = new TableColumn<>("Name");
    TableColumn<Person, String> gruppeCol = new TableColumn<>("Gruppe");
    TableColumn<Person, Arbeitgeber> arbCol = new TableColumn<>("Arbeitgeber");

    idCol.setCellValueFactory(new PropertyValueFactory<Person, Integer>("id"));
    nameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("name"));
    gruppeCol.setCellValueFactory(new PropertyValueFactory<Person, String>("gruppe"));
    arbCol.setCellValueFactory(new PropertyValueFactory<Person, Arbeitgeber>("arbeitgeber"));

    personTable.getColumns().addAll(idCol, nameCol, gruppeCol, arbCol);
    personTable.setTableMenuButtonVisible(true);
    return personTable;
}
}

我尝试过类似的事情:

for(TableColumn t : personTable.getColumns()){
  t.setVisible(false);
  t.setVisible(true);
}

但它不起作用。我想解决它没有排序。有没有人有想法?

感谢。

1 个答案:

答案 0 :(得分:2)

问题重述

据我所知,你有以下情况。

  1. 某人提及arbeitgeber
  2. 您在一个表格中显示arbeitgeber,在另一个表格中显示该人物。
  3. 人员表中有一个Arbeitgeber列,提供有关相关arbeitgeber的信息。
  4. 在arbeitgeber中,arbeitgeber的名称是可编辑的。
  5. 编辑arbeitgeber名称时,在arbeitgeber表中,您希望arbeitgeber的名称更新自动反映在您的人员表中。
  6. 解决方法

    1. 确保实体对象具有属性访问方法,以便可以观察各个实体字段的值以进行更改并采取适当的操作。

      public StringProperty nameProperty() {
          return name;
      }
      
    2. 在人员表中的Arbeitgeber列的单元格值与arbeitgeber名称之间设置绑定。

      在Java 7中:

      arbCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Person, String>, ObservableValue<String>>() {
          public ObservableValue<String> call(TableColumn.CellDataFeatures<Person, String> p) {
              return Bindings.selectString(
                  new ReadOnlyObjectWrapper<Object>(
                      p.getValue()
                  ), 
                  "arbeitgeber", "name"
              );
          }
      });
      

      在Java 8中:

      arbCol.setCellValueFactory(p -> 
          Bindings.selectString(p.getValue(), "arbeitgeber", "name")
      );
      
    3. 示例输出

      编辑快照之前和之后:

      unedited edited

      示例代码

      TableViewTest.java

      import javafx.application.Application;
      import javafx.beans.binding.Bindings;
      import javafx.beans.value.ObservableValue;
      import javafx.collections.FXCollections;
      import javafx.collections.ObservableList;
      import javafx.event.EventHandler;
      import javafx.scene.Scene;
      import javafx.scene.control.Label;
      import javafx.scene.control.TableColumn;
      import javafx.scene.control.TableView;
      import javafx.scene.control.cell.PropertyValueFactory;
      import javafx.scene.control.cell.TextFieldTableCell;
      import javafx.scene.layout.VBox;
      import javafx.stage.Stage;
      import javafx.util.Callback;
      
      public class TableViewTest extends Application {
      
          private TableView<Arbeitgeber> arbeitgeberTable;
          private TableView<Person> personTable;
      
          ObservableList<String> gruppeOptions =
              FXCollections.observableArrayList(
                      "Arbeiter",
                      "Angestellter",
                      "Leiter"
              );
      
          private ObservableList<Arbeitgeber> arbeitgeberListe = FXCollections.observableArrayList(new Arbeitgeber(1, "Goldgräber Inc."), new Arbeitgeber(2, "Hamster GmbH"), new Arbeitgeber(3, "Wissen"));
          private ObservableList<Person> personen = FXCollections.observableArrayList(
                  new Person(1, "Max Musterman", gruppeOptions.get(1), arbeitgeberListe.get(0)),
                  new Person(2, "Bernd Brot", gruppeOptions.get(0), arbeitgeberListe.get(0)),
                  new Person(3, "Fred Feuer", gruppeOptions.get(2), arbeitgeberListe.get(1)),
                  new Person(4, "Uli Stein", gruppeOptions.get(1), arbeitgeberListe.get(2)));
      
          @Override
          public void start(Stage primaryStage) throws Exception {
              createArbeitgeberTableview();
              createPersonTableview();
      
              VBox vbox = new VBox(15);
      
              Label aLabel = new Label("Arbeitgeber");
              Label pLabel = new Label("Personen");
              vbox.getChildren().addAll(aLabel, arbeitgeberTable, pLabel, personTable);
      
              Scene scene = new Scene(vbox);
              primaryStage.setScene(scene);
      
              primaryStage.show();
          }
      
          /**
           * @param args
           */
          public static void main(String[] args) {
              launch(args);
          }
      
          @SuppressWarnings({ "unchecked", "rawtypes" })
          private TableView<Arbeitgeber> createArbeitgeberTableview() {
              arbeitgeberTable = new TableView<>(arbeitgeberListe);
      
              arbeitgeberTable.setEditable(true);
      
              TableColumn<Arbeitgeber, Integer> idCol = new TableColumn<>("ID");
              TableColumn nameCol = new TableColumn<>("Name");
      
              idCol.setCellValueFactory(new PropertyValueFactory<Arbeitgeber, Integer>("id"));
              nameCol.setCellValueFactory(new PropertyValueFactory<Arbeitgeber, String>("name"));
      
      
              nameCol.setCellFactory(TextFieldTableCell.forTableColumn());
              nameCol.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<Arbeitgeber,String>>() {
      
                  @Override
                  public void handle(TableColumn.CellEditEvent<Arbeitgeber, String> event) {
                      ((Arbeitgeber) event.getTableView().getItems().get(event.getTablePosition().getRow())).setName(event.getNewValue());
      
                      for(Person p : personTable.getItems()) {
                          System.out.println(p.getArbeitgeber()); //shows the new value
                      }
                  }
              });
      
              arbeitgeberTable.getColumns().addAll(idCol, nameCol);
              arbeitgeberTable.setTableMenuButtonVisible(true);
              return arbeitgeberTable;
          }
      
          @SuppressWarnings("unchecked")
          private TableView<Person> createPersonTableview(){
              personTable = new TableView<>(personen);
      
              TableColumn<Person, Integer> idCol = new TableColumn<>("ID");
              TableColumn<Person, String> nameCol = new TableColumn<>("Name");
              TableColumn<Person, String> gruppeCol = new TableColumn<>("Gruppe");
              TableColumn<Person, String> arbCol = new TableColumn<>("Arbeitgeber");
      
              idCol.setCellValueFactory(new PropertyValueFactory<Person, Integer>("id"));
              nameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("name"));
              gruppeCol.setCellValueFactory(new PropertyValueFactory<Person, String>("gruppe"));
      
                arbCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Person, String>, ObservableValue<String>>() {
                    public ObservableValue<String> call(TableColumn.CellDataFeatures<Person, String> p) {
                        return Bindings.selectString(
                            new ReadOnlyObjectWrapper<Object>(
                                p.getValue()
                            ), 
                           "arbeitgeber", "name"
                        );
                    }
                });
      
              personTable.getColumns().addAll(idCol, nameCol, gruppeCol, arbCol);
              personTable.setTableMenuButtonVisible(true);
              return personTable;
          }
      }
      

      Person.java

      import javafx.beans.property.*;
      
      public class Person {
      
          private IntegerProperty id = new SimpleIntegerProperty();
          private StringProperty name = new SimpleStringProperty();
          private StringProperty gruppe = new SimpleStringProperty();
          private ObjectProperty<Arbeitgeber> arbeitgeber = new SimpleObjectProperty<>();
      
          public Person(int id, String name, String gruppe, Arbeitgeber arbeitgeber) {
              setId(id);
              setName(name);
              setGruppe(gruppe);
              setArbeitgeber(arbeitgeber);
          }
      
          public int getId() {
              return id.get();
          }
      
          public IntegerProperty idProperty() {
              return id;
          }
      
          public void setId(int id) {
              this.id.set(id);
          }
      
          public String getName() {
              return name.get();
          }
      
          public StringProperty nameProperty() {
              return name;
          }
      
          public void setName(String name) {
              this.name.set(name);
          }
      
          public String getGruppe() {
              return gruppe.get();
          }
      
          public StringProperty gruppeProperty() {
              return gruppe;
          }
      
          public void setGruppe(String gruppe) {
              this.gruppe.set(gruppe);
          }
      
          public Arbeitgeber getArbeitgeber() {
              return arbeitgeber.get();
          }
      
          public ObjectProperty<Arbeitgeber> arbeitgeberProperty() {
              return arbeitgeber;
          }
      
          public void setArbeitgeber(Arbeitgeber arbeitgeber) {
              this.arbeitgeber.set(arbeitgeber);
          }
      
          @Override
          public String toString() {
              return "Person{" +
                      "id=" + id +
                      ", name=" + name +
                      ", gruppe=" + gruppe +
                      ", arbeitgeber=" + arbeitgeber +
                      '}';
          }
      }
      

      Arbeitgeber.java

      import javafx.beans.property.IntegerProperty;
      import javafx.beans.property.SimpleIntegerProperty;
      import javafx.beans.property.SimpleStringProperty;
      import javafx.beans.property.StringProperty;
      
      public class Arbeitgeber {
          private IntegerProperty id = new SimpleIntegerProperty();
          private StringProperty name = new SimpleStringProperty();
      
          public Arbeitgeber(int id, String name) {
              setId(id);
              setName(name);
          }
      
          public IntegerProperty idProperty() {
              return id;
          }
      
          public int getId() {
              return id.get();
          }
      
          public void setId(int id) {
              this.id.set(id);
          }
      
          public StringProperty nameProperty() {
              return name;
          }
      
          public String getName() {
              return name.get();
          }
      
          public void setName(String name) {
              this.name.set(name);
          }
      
          @Override
          public String toString() {
              return "Arbeitgeber{" +
                      "id=" + id +
                      ", name=" + name +
                      '}';
          }
      }