JavaFX TableView 未立即更新

问题描述 投票:0回答:2

我对 JavaFX

TableView
UI 更新有问题。当我更改可观察对象后,它不会更新
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
2个回答
7
投票

由于

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

从 JavaFX 8u60 开始,您只需调用

refresh
TableView
方法,这将强制执行更新。


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

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


0
投票

对于仍在为此苦苦挣扎的人,请尝试这段代码:

for (int columnIndex = 0; columnIndex < tvModifications.getColumns().size(); columnIndex++) {
            TableColumn<ObservableList<String>, String> column = (TableColumn<ObservableList<String>, String>) tvModifications.getColumns().get(columnIndex);
            final int colIndex = columnIndex;
            column.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().get(colIndex)));
        }

设置项目后执行此操作。这将单独设置每个单元格的值,因为由于某种原因 JavaFX 会区分单元格值和表视图的项目!因此,即使您的 tableView 项目是正确的(通过调试得知),您仍然需要更新单元格值。

© www.soinside.com 2019 - 2024. All rights reserved.