SimpleStringProperty и SimpleIntegerProperty метод TableView в JavaFX

поэтому я пытаюсь узнать, как использовать JavaFx Tableview, и я наткнулся на этот учебник:

Oracle tableview учебник

в этом уроке они показывают, что для того, чтобы заполнить вас tableView вы должны заполнить его строками, но не только любую строку, которую вы должны отформатировать вас String до SimpleStringProperty

Я пробовал без формата, и результатом было то, что ни одна информация не будет отображаться!

также я обнаружил, что если вы хотите добавить Integer к таблице вы должны были бы объявить его как SimpleIntegerProperty

теперь я довольно новичок в JavaFx, но означает ли это, что при создании объекта я должен отформатировать все мои целые числа и строки, чтобы иметь возможность заполнить мой TableView? это кажется довольно глупым, но, может быть, есть более высокая цель? или есть способ избежать этого?

1 ответов


вам не нужно использовать свойства в объектах данных таблицы для их отображения, хотя использование свойств в определенных обстоятельствах желательно.

следующий код отобразит таблицу людей на основе класса Person, который имеет только строковые поля.

import javafx.application.Application;
import javafx.collections.*;
import javafx.geometry.Insets;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;

public class ReadOnlyTableView extends Application {
  private TableView<Person> table = new TableView<Person>();
  private final ObservableList<Person> data =
    FXCollections.observableArrayList(
      new Person("Jacob", "Smith", "jacob.smith@example.com"),
      new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
      new Person("Ethan", "Williams", "ethan.williams@example.com"),
      new Person("Emma", "Jones", "emma.jones@example.com"),
      new Person("Michael", "Brown", "michael.brown@example.com")
    );

  public static void main(String[] args) { launch(args); }

  @Override public void start(Stage stage) {
    stage.setTitle("Table View Sample");
    stage.setWidth(450);
    stage.setHeight(500);

    final Label label = new Label("Address Book");
    label.setFont(new Font("Arial", 20));

    TableColumn firstNameCol = new TableColumn("First Name");
    firstNameCol.setMinWidth(100);
    firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName"));

    TableColumn lastNameCol = new TableColumn("Last Name");
    lastNameCol.setMinWidth(100);
    lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName"));

    TableColumn emailCol = new TableColumn("Email");
    emailCol.setMinWidth(200);
    emailCol.setCellValueFactory(new PropertyValueFactory<Person, String>("email"));

    table.setItems(data);
    table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);

    final VBox vbox = new VBox();
    vbox.setSpacing(5);
    vbox.setPadding(new Insets(10, 0, 0, 10));
    vbox.getChildren().addAll(label, table);

    stage.setScene(new Scene(new Group(vbox)));
    stage.show();
  }

  public static class Person {
    private String firstName;
    private String lastName;
    private String email;

    private Person(String fName, String lName, String email) {
      this.firstName = fName;
      this.lastName = lName;
      this.email = email;
    }

    public String getFirstName() { return firstName; }
    public void setFirstName(String fName) { firstName = fName; }
    public String getLastName() { return lastName; }
    public void setLastName(String lName) { lastName = lName; }
    public String getEmail() { return email; }
    public void setEmail(String inMail) { email = inMail; }
  }
}

объяснение

цель использования свойств и ObservableLists заключается в том, что это прослушиваемые элементы. Когда используются свойства, если значение свойства атрибут в datamodel изменяется, представление элемента в TableView автоматически обновляется, чтобы соответствовать обновленному значению datamodel. Например, если для свойства электронной почты человека задано новое значение, это обновление будет отражено в TableView, поскольку оно прослушивает изменение свойства. Если вместо этого для представления электронной почты использовалась простая строка, TableView не будет обновляться, поскольку он не будет знать об изменениях значения электронной почты.

В PropertyValueFactory документация подробно описывает этот процесс:

пример использования этого класса:

TableColumn<Person,String> firstNameCol = new TableColumn<Person,String>("First Name");
firstNameCol.setCellValueFactory(new PropertyValueFactory<Person,String>("firstName"));  

в этом примере строка "firstName" используется в качестве ссылки на предполагаемый метод firstNameProperty () в типе класса Person (который тип класса списка элементов TableView). Кроме того, этот метод необходимо вернуть экземпляр свойства. Если метод встречает эти требования, а затем TableCell заполняется этим Observablevalue с. Кроме того, TableView автоматически добавит наблюдатель возвращаемого значения, так что любые изменения будут наблюдается TableView, в результате чего ячейка немедленно обновляется.

Если нет метода, соответствующего этому шаблону, существует провал поддержка попытки вызова get () или is () (что is, getFirstName() или isFirstName () в примере выше). Если метод соответствие этому шаблону существует, значение, возвращаемое этим методом завернутый в ReadOnlyObjectWrapper и вернулся к TableCell. Однако в этой ситуации это означает, что TableCell не будет способный наблюдать ObservableValue для изменений (как в случае первый подход выше).

обновление

вот контрастный пример к первому примеру, который демонстрирует, как TableView может наблюдать и автоматически обновляться на основе изменений в нем ObservableList элементов и изменения значения атрибута элемента на основе свойства.

import javafx.application.Application;
import javafx.beans.property.*;
import javafx.collections.*;
import javafx.event.*;
import javafx.geometry.Insets;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;

public class PropertyBasedTableView extends Application {
  private TableView<Person> table = new TableView<Person>();
  private final ObservableList<Person> data = FXCollections.observableArrayList();
  private void initData() {
    data.setAll(
      new Person("Jacob", "Smith", "jacob.smith@example.com"),
      new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
      new Person("Ethan", "Williams", "ethan.williams@example.com"),
      new Person("Emma", "Jones", "emma.jones@example.com"),
      new Person("Michael", "Brown", "michael.brown@example.com")
    );
  }

  public static void main(String[] args) { launch(args); }

  @Override public void start(Stage stage) {
    initData();

    stage.setTitle("Table View Sample");
    stage.setWidth(450);
    stage.setHeight(500);

    final Label label = new Label("Address Book");
    label.setFont(new Font("Arial", 20));

    TableColumn firstNameCol = new TableColumn("First Name");
    firstNameCol.setMinWidth(100);
    firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName"));

    TableColumn lastNameCol = new TableColumn("Last Name");
    lastNameCol.setMinWidth(100);
    lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName"));

    TableColumn emailCol = new TableColumn("Email");
    emailCol.setMinWidth(200);
    emailCol.setCellValueFactory(new PropertyValueFactory<Person, String>("email"));

    table.setItems(data);
    table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);
    table.setPrefHeight(300);

    final Button setEmailButton = new Button("Set first email in table to wizard@frobozz.com");
    setEmailButton.setOnAction(new EventHandler<ActionEvent>() {
      @Override public void handle(ActionEvent event) {
        if (data.size() > 0) {
          data.get(0).setEmail("wizard@frobozz.com");
        }  
      }
    });

    final Button removeRowButton = new Button("Remove first row from the table");
    removeRowButton.setOnAction(new EventHandler<ActionEvent>() {
      @Override public void handle(ActionEvent event) {
        if (data.size() > 0) {
          data.remove(0);
        }  
      }
    });

    final Button resetButton = new Button("Reset table data");
    resetButton.setOnAction(new EventHandler<ActionEvent>() {
      @Override public void handle(ActionEvent event) {
        initData();
      }
    });

    final VBox vbox = new VBox(10);
    vbox.setPadding(new Insets(10, 0, 0, 10));
    vbox.getChildren().addAll(label, table, setEmailButton, removeRowButton, resetButton);

    stage.setScene(new Scene(new Group(vbox)));
    stage.show();
  }

  public static class Person {
    private final StringProperty firstName;
    private final StringProperty lastName;
    private final StringProperty email;

    private Person(String fName, String lName, String email) {
      this.firstName = new SimpleStringProperty(fName);
      this.lastName = new SimpleStringProperty(lName);
      this.email = new SimpleStringProperty(email);
    }

    public String getFirstName() { return firstName.get(); }
    public void setFirstName(String fName) { firstName.set(fName); }
    public StringProperty firstNameProperty() { return firstName; }
    public String getLastName() { return lastName.get(); }
    public void setLastName(String lName) { lastName.set(lName); }
    public StringProperty lastNameProperty() { return lastName; }
    public String getEmail() { return email.get(); }
    public void setEmail(String inMail) { email.set(inMail); }
    public StringProperty emailProperty() { return email; }  // if this method is commented out then the tableview will not refresh when the email is set.
  }
}