【问题标题】:JavaFX TableView not updating immediatelyJavaFX TableView 没有立即更新
【发布时间】:2017-05-24 07:13:09
【问题描述】:

我对 JavaFX TableView UI 更新有疑问。在我更改 observable 对象后,它不会更新 TableView 的 UI。但是,如果我执行一个神奇的仪式,将TableView 的滚动条再次上下拉动——它似乎会重新绘制表格并更新其中的项目。 通过调试,我已确保 PreferencesSet ArrayList 和对象已正确更新。

Here's gif demonstration of what is happening

这是我第一次在这里提问,所以我可能会遗漏一些重要信息。随时问我。提前谢谢你。

这是代码(我省略了不相关的东西):

控制器类:

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;
}
}

}

【问题讨论】:

    标签: java user-interface javafx tableview


    【解决方案1】:

    由于 PropertyValueFactory 检索值的唯一方法是使用 getter,因此无法观察到属性的更改,因此只有在项目与新的 TableRow 关联时才会发生更新。

    从 JavaFX 8u60 开始,您可以简单地调用 TableView 的 refresh 方法,这将强制执行更新。


    然而,通常的做法是提供对包含属性值的属性对象的访问,例如

    在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

    【讨论】:

    • 我有一些 JPA 实体对象不能简单地更改为 IntegerProperty、StringProperty 等,因此排序根本不起作用。在“排序”事件上放置一个 table.refresh() 就可以了。非常感谢。
    猜你喜欢
    • 2016-08-06
    • 2013-11-07
    • 1970-01-01
    • 2016-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-02
    • 1970-01-01
    相关资源
    最近更新 更多