JavaFX TableView 未立即更新

标签 java user-interface javafx tableview

我在 JavaFX TableView UI 更新方面遇到问题。当我更改可观察对象后,它不会更新 TableView 的 UI。但是,如果我执行一个神奇的仪式,再次向下和向上拉动 TableView 的滚动条 - 它似乎会重新绘制表格并更新其中的项目。 通过调试,我确保 PreferencesSet ArrayList 和对象已正确更新。

Here's gif demonstration of what is happening

这是我第一次在这里提问,所以我可能遗漏了一些重要的信息。请随时向我索取。预先感谢您。

这是代码(我省略了不相关的内容):

Controller 类:

public class TestSomethingController implements Initializable {

public TableView<PreferenceValues.PreferencesSet> preferencesTable;
public TableColumn mdColumn;
public TableColumn typeColumn;
public TableColumn tradeColumn;
public TableColumn plastColumn;
public TableColumn capColumn;
public TableColumn multColumn;
public TableColumn sizeColumn;

@Override
public void initialize(URL location, ResourceBundle resources) {
    setNorthPanel();
    setTableColumns();
    fillAllInfo();
}

private void setTableColumns() {
    mdColumn.setCellValueFactory(new PropertyValueFactory<PreferenceValues.PreferencesSet, MarketDirection>("md"));
    typeColumn.setCellValueFactory(new PropertyValueFactory<PreferenceValues.PreferencesSet, UserOfferType>("type"));
    tradeColumn.setCellValueFactory(new PropertyValueFactory<PreferenceValues.PreferencesSet, Boolean>("trade"));
    plastColumn.setCellValueFactory(new PropertyValueFactory<PreferenceValues.PreferencesSet, Long>("plast"));
    capColumn.setCellValueFactory(new PropertyValueFactory<PreferenceValues.PreferencesSet, Double>("cap"));
    multColumn.setCellValueFactory(new PropertyValueFactory<PreferenceValues.PreferencesSet, Double>("mult"));
    sizeColumn.setCellValueFactory(new PropertyValueFactory<PreferenceValues.PreferencesSet, Long>("size"));
}      
private void fillAllInfo() {
     preferencesTable.setItems(FXCollections.observableArrayList(CurrentSession.currentUser.getPreferencesList()));
    fillNorthPanel();
}
public void applyClicked(ActionEvent actionEvent) {
    applyNorthPanelChanges();
}
private void applyNorthPanelChanges() {
    PreferenceValues.PreferencesSet preferencesSet = CurrentSession.currentUser.getPreferencesSet(dirChoiceBox.getSelectionModel().getSelectedItem(), offerTypeChoiceBox.getSelectionModel().getSelectedItem());
    preferencesSet.setTrade(tradeCheckBox.isSelected());
    preferencesSet.setPlast(plastSpinner.getValue());
    preferencesSet.setCap(capRateSpinner.getValue());
    preferencesSet.setMult(multSpinner.getValue());
    preferencesSet.setSize(sizeSpinner.getValue());
    preferencesSet.savePreferences();
}

用户类别:

public class User {

private PreferenceValues preferenceValues;


public PreferenceValues.PreferencesSet getPreferencesSet(MarketDirection md, UserOfferType userOfferType) {
    return preferenceValues.getPreferencesSet(md, userOfferType);
}

public ArrayList<PreferenceValues.PreferencesSet> getPreferencesList() {
    return preferenceValues.getPreferencesList();
}
}

PreferenceValues 类:

import java.util.ArrayList;
import java.util.TreeMap;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;

public class PreferenceValues {
private Preferences preferences;
private ArrayList<PreferencesSet> preferencesList;
private TreeMap<String, PreferencesSet> preferencesMap;

public PreferenceValues(User user) {
    preferencesList = new ArrayList<>();
    preferencesMap = new TreeMap<>();
    preferences = Preferences.userRoot().node("prefexample" + user.getwmId());
    for (MarketDirection md : MarketDirection.values()) {
        for (UserOfferType userOfferType : UserOfferType.values()) {
            if (userOfferType != UserOfferType.UNDEF) {
                PreferencesSet preferencesSet = new PreferencesSet(md, userOfferType, preferences);
                preferencesList.add(preferencesSet);
                preferencesMap.put(md.toString() + userOfferType.toString(), preferencesSet);
            }
        }
    }
}

protected ArrayList<PreferencesSet> getPreferencesList() {
    return preferencesList;
}

private String getMapKey(MarketDirection md, UserOfferType userOfferType) {
    return md.toString() + userOfferType.toString();
}

protected PreferencesSet getPreferencesSet(MarketDirection md, UserOfferType userOfferType) {
    return preferencesMap.get(getMapKey(md, userOfferType));
}

public void clear() throws BackingStoreException {
    preferences.clear();
}


public class PreferencesSet {
Preferences preferences;

private MarketDirection md;
private UserOfferType type;
private boolean trade;
private int plast;
private double cap;
private double mult;
private int size;


public PreferencesSet(MarketDirection md, UserOfferType type, Preferences preferences) {
    this.md = md;
    this.type = type;
    this.preferences = preferences;
    trade = preferences.node(md.toString()).node(type.toString()).getBoolean("trade", false);
    plast = preferences.node(md.toString()).node(type.toString()).getInt("plast", 222);
    cap = preferences.node(md.toString()).node(type.toString()).getDouble("cap", 333);
    mult = preferences.node(md.toString()).node(type.toString()).getDouble("mult", 1);
    size = preferences.node(md.toString()).node(type.toString()).getInt("size", 15000);
}

public void savePreferences() {
    preferences.node(md.toString()).node(type.toString()).putBoolean("trade", trade);
    preferences.node(md.toString()).node(type.toString()).putInt("plast", plast);
    preferences.node(md.toString()).node(type.toString()).putDouble("cap", cap);
    preferences.node(md.toString()).node(type.toString()).putDouble("mult", mult);
    preferences.node(md.toString()).node(type.toString()).putInt("size", size);
}

public MarketDirection getMd() {
    return md;
}

public UserOfferType getType() {
    return type;
}

public boolean isTrade() {
    return trade;
}

public int getPlast() {
    return plast;
}

public double getCap() {
    return cap;
}

public double getMult() {
    return mult;
}

public int getSize() {
    return size;
}

public void setTrade(boolean trade) {
    this.trade = trade;
}

public void setPlast(int plast) {
    this.plast = plast;
}

public void setCap(double cap) {
    this.cap = cap;
}

public void setMult(double mult) {
    this.mult = mult;
}

public void setSize(int size) {
    this.size = size;
}
}

}

最佳答案

由于 PropertyValueFactory 检索值的唯一方法是使用 getter,因此无法观察到属性的更改,因此仅当该项目与新的 关联时才会发生更新表行

从 JavaFX 8u60 开始,您只需调用 TableViewrefresh 方法,这将强制执行更新。

<小时/>

但是,通常的方法是提供对包含属性值的属性对象的访问,例如

PreferencesSet

private final IntegerProperty plast = new SimpleIntegerProperty(); 

public void setPlast(int plast) {
    this.plast.set(plast);
}

public int getPlast() {
    return plast.get();
}

// this method will be used by the PropertyValueFactory
// and returns a Property which notifies TableView of changes
public IntegerProperty plastProperty() {
    return plast;
}

其他数据类型还有其他属性类型,请参阅 javafx.beans.property package

关于JavaFX TableView 未立即更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41557957/

相关文章:

java - 如何从 <form target ="IFrame"> 得到响应

java - 如何从java实例化在scala中定义的嵌套泛型类?

java - 错误(Wildfly 11 服务器为 389/703

java - Flume HDFS接收器自定义文件名

java - 如何在 JavaFX 中恢复按钮的 onclick 效果

c++ - createButton OpenCV 新 Qt 功能

user-interface - 我应该隐藏还是销毁 UI 元素?

java - 使用此问题中提供的数据递归创建 TreeView?

java - 从 Controller 访问 FXML 中的重复控件,无需为每个控件提供 ID

java - 如何编辑 JFXSpinner 内部文本