Программное обновление текста в ячейке TableView - Java

Узнай цену своей работы

Формулировка задачи:

Доброго дня. Есть программа отображающая в TableView информацию. В процессе её работы информация меняется и возникает необходимость обновления текста в ячейках таблицы. Для понимания приведу простой пример:
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
 
public class Test extends Application {
 
    private TableView<Person> table = new TableView<Person>();
    private final ObservableList<Person> data =
            FXCollections.observableArrayList(
            new Person("Jacob"),
            new Person("Isabella"),
            new Person("Ethan"),
            new Person("Emma"),
            new Person("Michael"));
    final HBox hb = new HBox();
 
    public static void main(String[] args) {
        launch(args);
    }
 
    @Override
    public void start(Stage stage) {
        Scene scene = new Scene(new Group());
        stage.setTitle("Table View Sample");
        stage.setWidth(450);
        stage.setHeight(550);
 
        table.setEditable(true);
 
        TableColumn firstNameCol = new TableColumn("First Name");
        firstNameCol.setMinWidth(100);
        firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName"));
 
        table.setItems(data);
        table.getColumns().add(firstNameCol);
 
        final Button button1 = new Button("Edit1");
        button1.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent e) {
System.out.println(data.get(2).getFirstName());
data.get(2).setFirstName("abcdef");
System.out.println(data.get(2).getFirstName());
            }
        });
 
        final Button button2 = new Button("Edit2");
        button2.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent e) {
Person temp = data.get(2);
temp.setFirstName("ghijkl");
data.set(2,temp);
            }
        });
 
        hb.getChildren().addAll(button1, button2);
        hb.setSpacing(3);
 
        final VBox vbox = new VBox();
        vbox.setSpacing(5);
        vbox.setPadding(new Insets(10, 0, 0, 10));
        vbox.getChildren().addAll(table, hb);
 
        ((Group) scene.getRoot()).getChildren().addAll(vbox);
 
        stage.setScene(scene);
        stage.show();
    }
 
    public static class Person {
 
        private final SimpleStringProperty firstName;
 
        private Person(String fName) {
            this.firstName = new SimpleStringProperty(fName);
        }
 
        public String getFirstName() {
            return firstName.get();
        }
        public void setFirstName(String fName) {
            firstName.set(fName);
        }
    }
}
Если менять текст в объекте (как по нажатию кнопки button1) то значение поля в объекте меняется (это можно видеть по выводу в консоль "до" и "после") но TableView отображает старое значение (оно и понятно - ObservableList ничего не знает о том, что в полях объекта что-то изменилось). Для себя нашёл пока способ "обновления" информации - как по нажатию кнопки button2. Больше никаких идей в голову не пришло, пока не очень хорошо знаком с java. Подскажите, как сообщить ObservableList или TableView о том, что нужно "перерисовать" ячейку или строку?

Решение задачи: «Программное обновление текста в ячейке TableView»

textual
Листинг программы
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
 
public class Test extends Application {
 
    final HBox hb = new HBox();
    private final ObservableList<Person> data =
            FXCollections.observableArrayList(
                    new Person("Jacob"),
                    new Person("Isabella"),
                    new Person("Ethan"),
                    new Person("Emma"),
                    new Person("Michael"));
    private TableView<Person> table = new TableView<>();
 
    public static void main(String[] args) {
        launch(args);
    }
 
    @Override
    public void start(Stage stage) {
        Scene scene = new Scene(new Group());
        stage.setTitle("Table View Sample");
        stage.setWidth(450);
        stage.setHeight(550);
 
        Person.setTable(table);
        table.setEditable(true);
 
        TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");
        firstNameCol.setMinWidth(100);
        firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstName"));
 
        table.setItems(data);
        table.getColumns().add(firstNameCol);
 
 
        final Button button1 = new Button("Edit1");
        button1.setOnAction(e -> {
            System.out.println(data.get(2).getFirstName());
            data.get(2).setFirstName("abcdef");
            System.out.println(data.get(2).getFirstName());
        });
 
        final Button button2 = new Button("Edit2");
        button2.setOnAction(e -> {
            Person temp = data.get(2);
            temp.setFirstName("ghijkl");
            data.set(2, temp);
        });
 
        hb.getChildren().addAll(button1, button2);
        hb.setSpacing(3);
 
        final VBox vbox = new VBox();
        vbox.setSpacing(5);
        vbox.setPadding(new Insets(10, 0, 0, 10));
        vbox.getChildren().addAll(table, hb);
 
        ((Group) scene.getRoot()).getChildren().addAll(vbox);
 
        stage.setScene(scene);
        stage.show();
    }
 
    public static class Person {
        static TableView table;
 
        private final SimpleStringProperty firstName;
 
        private Person(String fName) {
            this.firstName = new SimpleStringProperty(fName);
        }
 
        public String getFirstName() {
            return firstName.get();
        }
 
        public void setFirstName(String fName) {
            firstName.set(fName);
            table.refresh();
        }
 
        static void setTable(TableView<Person> table) {
            Person.table = table;
        }
    }
}

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

15   голосов , оценка 3.933 из 5