JavaFX TableView不会立即更新

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

这是gif演示正在发生的事情

这是我第一次在这里提问,所以我可能遗漏了一些重要的信息。 随意问我这个问题。 先感谢您。

这是代码(我遗漏了不相关的东西):

ControllerClass:

 public class TestSomethingController implements Initializable { public TableView 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("md")); typeColumn.setCellValueFactory(new PropertyValueFactory("type")); tradeColumn.setCellValueFactory(new PropertyValueFactory("trade")); plastColumn.setCellValueFactory(new PropertyValueFactory("plast")); capColumn.setCellValueFactory(new PropertyValueFactory("cap")); multColumn.setCellValueFactory(new PropertyValueFactory("mult")); sizeColumn.setCellValueFactory(new PropertyValueFactory("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 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 preferencesList; private TreeMap 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 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,因此无法观察属性的更改,因此只有在项与新TableRow关联时才会发生更新。

从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