SimpleStringProperty и SimpleIntegerProperty TableView JavaFX

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

Руководство по просмотру таблиц Oracle

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

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

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

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

 OrdinaryDraft14 мар. 2019 г., 13:04
Я согласен, что эти учебники неt демонстрирует много возможностей и тем.
 Andrew S03 апр. 2016 г., 23:17
Это'плохо написанное руководство. Они затеняют слишком много важных моментов, например, Generics.

Ответы на вопрос(1)

Решение Вопроса

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

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

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 table = new TableView();
  private final ObservableList data =
    FXCollections.observableArrayList(
      new Person("Jacob", "Smith", "[email protected]"),
      new Person("Isabella", "Johnson", "[email protected]"),
      new Person("Ethan", "Williams", "[email protected]"),
      new Person("Emma", "Jones", "[email protected]"),
      new Person("Michael", "Brown", "[email protected]")
    );

  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("firstName"));

    TableColumn lastNameCol = new TableColumn("Last Name");
    lastNameCol.setMinWidth(100);
    lastNameCol.setCellValueFactory(new PropertyValueFactory("lastName"));

    TableColumn emailCol = new TableColumn("Email");
    emailCol.setMinWidth(200);
    emailCol.setCellValueFactory(new PropertyValueFactory("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; }
  }
}

объяснение

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

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

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

TableColumn firstNameCol = new TableColumn("First Name");
firstNameCol.setCellValueFactory(new PropertyValueFactory("firstName"));  

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

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

Обновить

Вот контрастный пример с первым примером, который демонстрирует, как TableView может наблюдать и автоматически обновлять, основываясь на его изменениях ».s 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 table = new TableView();
  private final ObservableList data = FXCollections.observableArrayList();
  private void initData() {
    data.setAll(
      new Person("Jacob", "Smith", "[email protected]"),
      new Person("Isabella", "Johnson", "[email protected]"),
      new Person("Ethan", "Williams", "[email protected]"),
      new Person("Emma", "Jones", "[email protected]"),
      new Person("Michael", "Brown", "[email protected]")
    );
  }

  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("firstName"));

    TableColumn lastNameCol = new TableColumn("Last Name");
    lastNameCol.setMinWidth(100);
    lastNameCol.setCellValueFactory(new PropertyValueFactory("lastName"));

    TableColumn emailCol = new TableColumn("Email");
    emailCol.setMinWidth(200);
    emailCol.setCellValueFactory(new PropertyValueFactory("email"));

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

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

    final Button removeRowButton = new Button("Remove first row from the table");
    removeRowButton.setOnAction(new EventHandler() {
      @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() {
      @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.
  }
}
 jewelsea14 нояб. 2012 г., 21:30
Добавил цитату из PropertyValueFactory в ответ на адрес Marc 'Дополнительный вопрос.
 Marc Rasmussen14 нояб. 2012 г., 23:13
я могу видеть, что вы используете публичный StringProperty emailProperty () это всегда необходимо? или вы можете сделать это с помощью простого getEmail ()?
 Marc Rasmussen14 нояб. 2012 г., 21:06
Прежде всего, большое спасибо за ваш ответ, если бы мог, я бы дал вам больше 1-го пальца :) Во-вторых, что вы скажете, что при преобразовании строк в свойство SimpleStringProperty таблица будет автоматически обновляться? И выбрав не вам придется обновлять таблицу вручную?
 Marc Rasmussen14 нояб. 2012 г., 22:50
Вы, сэр! Вы заслуживаете медали, спасибо, что терпите меня! последняя вещь, хотя почему классный человек статичен
 Andrew S04 апр. 2016 г., 00:10
Должны ли средства доступа заканчиваться словом «свойство»? Кажется абсурдным, что мы должны изменить наши объекты модели, чтобы они соответствовали требованиям наших объектов просмотра Есть ли способ сделать это без изменения уже построенных моделей объектов с помощью типичных методов getX и setX?
 Asif Mushtaq16 июн. 2016 г., 09:41
@ AndrewS it 'Требуется соглашение об именовании, как описано в JavaBeans.docs.oracle.com/javase/8/javafx/properties-binding-tutorial/... в этой ссылке перейти кПонимание собственности »
 jewelsea14 нояб. 2012 г., 23:15
 Andrew S04 апр. 2016 г., 01:24
Разобрался, просто точка, которую я обнаружил, PropertyValueFactory требовательна к регистру. Например, если мой метод доступа называется getLastName (), то в PropertyFactory я могу использовать lastName или LastName, но не фамилию. Когда у меня был метод доступа с именем getlastName, он мне тоже не понравился из-за строчной буквы L на последней.
 Marc Rasmussen14 нояб. 2012 г., 22:23
будет ли таблица обновляться автоматически при изменении одного из свойств и если да, то как вы это сделаете? изменить список или установить значение, используя object.setName () (в качестве примера)
 jewelsea14 нояб. 2012 г., 22:48
Добавлен дополнительный пример, демонстрирующий, как заставить таблицу обновляться автоматически при изменении значения свойства или при изменении списка, поддерживающего представление таблицы.
 jewelsea14 нояб. 2012 г., 23:10
В приведенном примере использование статического классификатора для класса person является излишним; то есть он будет работать с этим классификатором или без него. Увидетьучебник по вложенным классам чтобы понять, что делает статический вложенный класс.

Ваш ответ на вопрос