JavaFX Tableview прослушивает изменения только один раз - PullRequest
0 голосов
/ 12 апреля 2020

Я занимаюсь разработкой простого приложения Addressbook. Я использую шаблон проектирования DAO, класс Singleton и ленивую инициализацию. Я следую основам здесь .

Но я работаю над этим и добавляю Persistent layer. Также немного простой дизайн patterns, как я уже сказал. Я создал личность, которая действует как моя model class. причина отсутствия поддержки сериализации в классах свойств FX, которые я реализую Externalizable. здесь Person Class:

    private StringProperty name;
    private String _name;
    @Column(name = "name")
    public String getName() { 
        if(name==null) { 
            return _name;
        } else { 
            return name.get();
        }
    }
    public StringProperty nameProperty() { 
        if(name==null) { 
            name=new SimpleStringProperty(_name);
            }
        return name;       
    }
    public void setName(String name) { 
        if(this.name==null) { 
            _name=name;
        } else  { 
            this.name.set(name);
        }
    }
    // All the fields has super-lazy initialization like above.
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeInt(getPersonId());
        out.writeObject(getName());
        out.writeObject(getLastname());
        out.writeObject(getPostalcode());
        out.writeObject(getCity());
        out.writeObject(getStreet());
    }
    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        setPersonId(in.readInt());
        setName((String)in.readObject());
        setLastname((String) in.readObject());
        setCity((String) in.readObject());
        setStreet((String) in.readObject());
        setPostalcode((String) in.readObject());
    }
}

Также я создал PersonDAO Интерфейс А PersonDAOImpl. PersonDAO содержит метод с именем getAll(), который возвращает ArrayList. Он должен извлечь всех людей из БД и добавить их в ArrayList. Сигнатура метода:

    public abstract List<T> getAll();

Реализация в PersonDAOImp выглядит примерно так:

    @Override
public List<Person> getAll() {
   persons.clear();
   persons=getConnection().beginTransaction().
           createNamedQuery("Person.findAll").getResultList();
   return persons;
}

Какая ссылка person является ArrayList. (Нам не важно, что делает getConnection (), потому что здесь проблема не в этом; этот метод устанавливает соединение сущностей с БД). Я знаю, если я хочу работать с слушателями FX, я должен использовать ObservableList Collection. При использовании метода getAll() я делаю что-то вроде этого:

    List personArrayList = this.personDAOImpl.getAll();
    ObservableList<Person> persons=FXCollections.observableArrayList(personArrayList);  

И передаю это ObservableList с именем persons в TableView. После этого я добавил слушателя в табличное представление, которое слушает изменение выбранного человека. При выборе одного из лиц данные о человеке переходят к некоторым ярлыкам в форме; есть метод с именем showPersonDetails(), который отвечает за это. И вот оно:

        personTable.getSelectionModel().selectedItemProperty().addListener(
            (observable, oldValue, newValue) -> { 
                   showPersonDetails(newValue);
            });

Я поместил этот код в метод Initialize PersonController. Теперь, когда я запускаю приложение, я вижу, что табличное представление заполнено persons из database. Когда я нажимаю на одного из людей, он печатает сведения о человеке в эти ярлыки только в первый раз. (Через showPersonDetails) Когда я нажимаю на другого человека, он не вызывает метод showPersonDetails. Если вы спрашиваете, что является реализацией метода showPersonDetails, вот он:

public void showPersonDetails(Person person)  { 
    if(person != null) { 
    this.firstNameLabel.setText(person.getName());
    this.lastNameLabel.setText(person.getLastname());
    this.cityLabel.setText(person.getCity());
    this.streetLabel.setText(person.getStreet());
    this.postalcodeLabel.setText(person.getPostalcode());
    } else {
    this.firstNameLabel.setText("");
    this.lastNameLabel.setText("");
    this.cityLabel.setText("");
    this.streetLabel.setText("");
    this.postalcodeLabel.setText("");            
    }
}

На самом деле слушатель действует только один раз. Я поместил какой-то другой код в lambda expression suck как вывод значения stati c, чтобы увидеть, слушает ли слушатель эти изменения? И я вижу, что он не слушает изменения после первого раза; и только на первое время.

Вопрос в том, почему это так? Что не так по логике? Любая помощь будет оценена.

...