当基础数据更改时,TreeTableView 单元格不会更新
TreeTableView cells does not get updated when underlying data changes
我正在编写一个在 JFXTreeTableView 中显示实时报价的市场观察程序,但是当我更新 ObservableList 中的数据时,它不会在 JFXTreeTableView 中更新。 changeDataDemo() 方法实际上跟踪价格变化并且工作正常(我正在使用 RethinkDB changefeeds 来完成它。)但是我已经删除了此处的 changefeed 代码以提高可读性。有一种方法可以将行添加到 TreeTableView 并且工作正常,但我已从此处删除了代码。
这是我的代码:
public class MainWindow implements Initializable {
private ObservableList<MarketWatchEntry> marketWatchEntries = FXCollections.observableArrayList();
private JFXTreeTableColumn<MarketWatchEntry, String> instrument_token_col;
private JFXTreeTableColumn<MarketWatchEntry, String> exchange_col;
private JFXTreeTableColumn<MarketWatchEntry, String> instrument_type_col;
private JFXTreeTableColumn<MarketWatchEntry, String> symbol_col;
private JFXTreeTableColumn<MarketWatchEntry, String> expiry_col;
private JFXTreeTableColumn<MarketWatchEntry, Number> buy_qty_col;
private JFXTreeTableColumn<MarketWatchEntry, Number> buy_price_col;
private JFXTreeTableColumn<MarketWatchEntry, Number> seller_price_col;
private JFXTreeTableColumn<MarketWatchEntry, Number> sell_qty_col;
@FXML
private JFXTreeTableView<MarketWatchEntry> MarketWatch;
@Override
public void initialize(URL location, ResourceBundle resources) {
populateMarketWatch();
}
private void populateMarketWatch() {
instrument_token_col = new JFXTreeTableColumn<>("Instrument Token");
instrument_token_col.setPrefWidth(80);
instrument_token_col.setVisible(false);
instrument_token_col.setCellValueFactory((TreeTableColumn.CellDataFeatures<MarketWatchEntry, String> param) -> param.getValue().getValue().instrument_token);
exchange_col = new JFXTreeTableColumn<>("Exchange");
exchange_col.setPrefWidth(80);
exchange_col.setCellValueFactory((TreeTableColumn.CellDataFeatures<MarketWatchEntry, String> param) -> param.getValue().getValue().exchange);
instrument_type_col = new JFXTreeTableColumn<>("Instrument");
instrument_type_col.setPrefWidth(80);
instrument_type_col.setCellValueFactory((TreeTableColumn.CellDataFeatures<MarketWatchEntry, String> param) -> param.getValue().getValue().instrument_type);
symbol_col = new JFXTreeTableColumn<>("Symbol");
symbol_col.setPrefWidth(80);
symbol_col.setCellValueFactory((TreeTableColumn.CellDataFeatures<MarketWatchEntry, String> param) -> param.getValue().getValue().trading_symbol);
expiry_col = new JFXTreeTableColumn<>("Expiry");
expiry_col.setPrefWidth(80);
expiry_col.setCellValueFactory((TreeTableColumn.CellDataFeatures<MarketWatchEntry, String> param) -> param.getValue().getValue().expiry);
buy_qty_col = new JFXTreeTableColumn<>("Buy Qty");
buy_qty_col.setPrefWidth(80);
buy_qty_col.setCellValueFactory((TreeTableColumn.CellDataFeatures<MarketWatchEntry, Number> param) -> param.getValue().getValue().buy_qty);
buy_price_col = new JFXTreeTableColumn<>("Buyer Price");
buy_price_col.setPrefWidth(80);
buy_price_col.setCellValueFactory((JFXTreeTableColumn.CellDataFeatures<MarketWatchEntry, Number> param) -> param.getValue().getValue().buyer_price);
seller_price_col = new JFXTreeTableColumn<>("Seller Price");
seller_price_col.setPrefWidth(80);
seller_price_col.setCellValueFactory((TreeTableColumn.CellDataFeatures<MarketWatchEntry, Number> param) -> param.getValue().getValue().seller_price);
sell_qty_col = new JFXTreeTableColumn<>("Sell Qty");
sell_qty_col.setPrefWidth(80);
sell_qty_col.setCellValueFactory((TreeTableColumn.CellDataFeatures<MarketWatchEntry, Number> param) -> param.getValue().getValue().sell_qty);
final TreeItem<MarketWatchEntry> root = new RecursiveTreeItem<>(marketWatchEntries, RecursiveTreeObject::getChildren);
MarketWatch.getColumns().setAll(instrument_token_col, exchange_col, instrument_type_col, symbol_col, expiry_col,
buy_qty_col, buy_price_col, seller_price_col, sell_qty_col, ltp_col, ltq_col, open_price_col, high_price_col,
low_price_col, close_price_col, average_price_col, change_col, net_change_col);
MarketWatch.setRoot(root);
MarketWatch.setShowRoot(false);
}
private void changeDataDemo() {
marketWatchEntries.get(0).buyer_price = new SimpleDoubleProperty(100);
}
}
我删除了不相关的代码块以提高可读性。
我的问题是如何让 TreeTableView 在使用新数据更新集合时更新所有单元格。
MarketWatchEntry class
class MarketWatchEntry extends RecursiveTreeObject<MarketWatchEntry> {
StringProperty instrument_token;
StringProperty exchange;
StringProperty instrument_type;
StringProperty trading_symbol;
StringProperty expiry;
DoubleProperty buy_qty;
DoubleProperty buyer_price;
DoubleProperty seller_price;
DoubleProperty sell_qty;
DoubleProperty last_price;
DoubleProperty last_qty;
DoubleProperty open_price;
DoubleProperty high_price;
DoubleProperty low_price;
DoubleProperty close_price;
DoubleProperty average_price;
DoubleProperty change;
DoubleProperty net_change;
public MarketWatchEntry(String instrument_token, String exchange, String instrument_type, String trading_symbol,
String expiry, double buy_qty, double buy_price, double sell_price, double sell_qty,
double last_price, double last_qty, double open_price, double high_price, double low_price,
double close_price, double average_price, double change, double net_change) {
this.instrument_token = new SimpleStringProperty(instrument_token);
this.exchange = new SimpleStringProperty(exchange);
this.instrument_type = new SimpleStringProperty(instrument_type);
this.trading_symbol = new SimpleStringProperty(trading_symbol);
this.expiry = new SimpleStringProperty(expiry);
this.buy_qty = new SimpleDoubleProperty(buy_qty);
this.buyer_price = new SimpleDoubleProperty(buy_price);
this.sell_qty = new SimpleDoubleProperty(sell_qty);
this.seller_price = new SimpleDoubleProperty(sell_price);
this.last_price = new SimpleDoubleProperty(last_price);
this.last_qty = new SimpleDoubleProperty(last_qty);
this.open_price = new SimpleDoubleProperty(open_price);
this.high_price = new SimpleDoubleProperty(high_price);
this.low_price = new SimpleDoubleProperty(low_price);
this.close_price = new SimpleDoubleProperty(close_price);
this.average_price = new SimpleDoubleProperty(average_price);
this.change = new SimpleDoubleProperty(change);
this.net_change = new SimpleDoubleProperty(net_change);
}
@Override
public boolean equals(Object obj) {
if (obj == null || getClass() != obj.getClass()) {
return false;
}
return this.instrument_token.getValue().equals(((MarketWatchEntry) obj).instrument_token.getValue());
}
@Override
public int hashCode() {
return 7 + 5 * Integer.valueOf(instrument_token.getValue());
}
}
问题出在您的 changeDataDemo
方法中:
private void changeDataDemo() {
marketWatchEntries.get(0).buyer_price = new SimpleDoubleProperty(100);
}
您正在创建属性的新实例,而不是更改它们的值。
像这样的东西有效:
private void changeDataDemo() {
marketWatchEntries.get(0).buyer_price.set(100);
}
但建议在您的实体上提供 setters/getters class:
class MarketWatchEntry extends RecursiveTreeObject<MarketWatchEntry> {
private final DoubleProperty buyer_price;
...
public MarketWatchEntry(String instrument_token, String exchange, String instrument_type, String trading_symbol,
String expiry, double buy_qty, double buy_price, double sell_price, double sell_qty) {
...
this.buyer_price = new SimpleDoubleProperty(buy_price);
...
}
public final DoubleProperty buyer_priceProperty() {
return buyer_price;
}
public final double getBuyer_price() {
return buyer_price.get();
}
public final void setBuyer_price(double value) {
buyer_price.set(value);
}
...
}
所以你可以打电话:
private void changeDataDemo() {
marketWatchEntries.get(0).setBuyer_price(100);
}
我正在编写一个在 JFXTreeTableView 中显示实时报价的市场观察程序,但是当我更新 ObservableList 中的数据时,它不会在 JFXTreeTableView 中更新。 changeDataDemo() 方法实际上跟踪价格变化并且工作正常(我正在使用 RethinkDB changefeeds 来完成它。)但是我已经删除了此处的 changefeed 代码以提高可读性。有一种方法可以将行添加到 TreeTableView 并且工作正常,但我已从此处删除了代码。
这是我的代码:
public class MainWindow implements Initializable {
private ObservableList<MarketWatchEntry> marketWatchEntries = FXCollections.observableArrayList();
private JFXTreeTableColumn<MarketWatchEntry, String> instrument_token_col;
private JFXTreeTableColumn<MarketWatchEntry, String> exchange_col;
private JFXTreeTableColumn<MarketWatchEntry, String> instrument_type_col;
private JFXTreeTableColumn<MarketWatchEntry, String> symbol_col;
private JFXTreeTableColumn<MarketWatchEntry, String> expiry_col;
private JFXTreeTableColumn<MarketWatchEntry, Number> buy_qty_col;
private JFXTreeTableColumn<MarketWatchEntry, Number> buy_price_col;
private JFXTreeTableColumn<MarketWatchEntry, Number> seller_price_col;
private JFXTreeTableColumn<MarketWatchEntry, Number> sell_qty_col;
@FXML
private JFXTreeTableView<MarketWatchEntry> MarketWatch;
@Override
public void initialize(URL location, ResourceBundle resources) {
populateMarketWatch();
}
private void populateMarketWatch() {
instrument_token_col = new JFXTreeTableColumn<>("Instrument Token");
instrument_token_col.setPrefWidth(80);
instrument_token_col.setVisible(false);
instrument_token_col.setCellValueFactory((TreeTableColumn.CellDataFeatures<MarketWatchEntry, String> param) -> param.getValue().getValue().instrument_token);
exchange_col = new JFXTreeTableColumn<>("Exchange");
exchange_col.setPrefWidth(80);
exchange_col.setCellValueFactory((TreeTableColumn.CellDataFeatures<MarketWatchEntry, String> param) -> param.getValue().getValue().exchange);
instrument_type_col = new JFXTreeTableColumn<>("Instrument");
instrument_type_col.setPrefWidth(80);
instrument_type_col.setCellValueFactory((TreeTableColumn.CellDataFeatures<MarketWatchEntry, String> param) -> param.getValue().getValue().instrument_type);
symbol_col = new JFXTreeTableColumn<>("Symbol");
symbol_col.setPrefWidth(80);
symbol_col.setCellValueFactory((TreeTableColumn.CellDataFeatures<MarketWatchEntry, String> param) -> param.getValue().getValue().trading_symbol);
expiry_col = new JFXTreeTableColumn<>("Expiry");
expiry_col.setPrefWidth(80);
expiry_col.setCellValueFactory((TreeTableColumn.CellDataFeatures<MarketWatchEntry, String> param) -> param.getValue().getValue().expiry);
buy_qty_col = new JFXTreeTableColumn<>("Buy Qty");
buy_qty_col.setPrefWidth(80);
buy_qty_col.setCellValueFactory((TreeTableColumn.CellDataFeatures<MarketWatchEntry, Number> param) -> param.getValue().getValue().buy_qty);
buy_price_col = new JFXTreeTableColumn<>("Buyer Price");
buy_price_col.setPrefWidth(80);
buy_price_col.setCellValueFactory((JFXTreeTableColumn.CellDataFeatures<MarketWatchEntry, Number> param) -> param.getValue().getValue().buyer_price);
seller_price_col = new JFXTreeTableColumn<>("Seller Price");
seller_price_col.setPrefWidth(80);
seller_price_col.setCellValueFactory((TreeTableColumn.CellDataFeatures<MarketWatchEntry, Number> param) -> param.getValue().getValue().seller_price);
sell_qty_col = new JFXTreeTableColumn<>("Sell Qty");
sell_qty_col.setPrefWidth(80);
sell_qty_col.setCellValueFactory((TreeTableColumn.CellDataFeatures<MarketWatchEntry, Number> param) -> param.getValue().getValue().sell_qty);
final TreeItem<MarketWatchEntry> root = new RecursiveTreeItem<>(marketWatchEntries, RecursiveTreeObject::getChildren);
MarketWatch.getColumns().setAll(instrument_token_col, exchange_col, instrument_type_col, symbol_col, expiry_col,
buy_qty_col, buy_price_col, seller_price_col, sell_qty_col, ltp_col, ltq_col, open_price_col, high_price_col,
low_price_col, close_price_col, average_price_col, change_col, net_change_col);
MarketWatch.setRoot(root);
MarketWatch.setShowRoot(false);
}
private void changeDataDemo() {
marketWatchEntries.get(0).buyer_price = new SimpleDoubleProperty(100);
}
}
我删除了不相关的代码块以提高可读性。 我的问题是如何让 TreeTableView 在使用新数据更新集合时更新所有单元格。
MarketWatchEntry class
class MarketWatchEntry extends RecursiveTreeObject<MarketWatchEntry> {
StringProperty instrument_token;
StringProperty exchange;
StringProperty instrument_type;
StringProperty trading_symbol;
StringProperty expiry;
DoubleProperty buy_qty;
DoubleProperty buyer_price;
DoubleProperty seller_price;
DoubleProperty sell_qty;
DoubleProperty last_price;
DoubleProperty last_qty;
DoubleProperty open_price;
DoubleProperty high_price;
DoubleProperty low_price;
DoubleProperty close_price;
DoubleProperty average_price;
DoubleProperty change;
DoubleProperty net_change;
public MarketWatchEntry(String instrument_token, String exchange, String instrument_type, String trading_symbol,
String expiry, double buy_qty, double buy_price, double sell_price, double sell_qty,
double last_price, double last_qty, double open_price, double high_price, double low_price,
double close_price, double average_price, double change, double net_change) {
this.instrument_token = new SimpleStringProperty(instrument_token);
this.exchange = new SimpleStringProperty(exchange);
this.instrument_type = new SimpleStringProperty(instrument_type);
this.trading_symbol = new SimpleStringProperty(trading_symbol);
this.expiry = new SimpleStringProperty(expiry);
this.buy_qty = new SimpleDoubleProperty(buy_qty);
this.buyer_price = new SimpleDoubleProperty(buy_price);
this.sell_qty = new SimpleDoubleProperty(sell_qty);
this.seller_price = new SimpleDoubleProperty(sell_price);
this.last_price = new SimpleDoubleProperty(last_price);
this.last_qty = new SimpleDoubleProperty(last_qty);
this.open_price = new SimpleDoubleProperty(open_price);
this.high_price = new SimpleDoubleProperty(high_price);
this.low_price = new SimpleDoubleProperty(low_price);
this.close_price = new SimpleDoubleProperty(close_price);
this.average_price = new SimpleDoubleProperty(average_price);
this.change = new SimpleDoubleProperty(change);
this.net_change = new SimpleDoubleProperty(net_change);
}
@Override
public boolean equals(Object obj) {
if (obj == null || getClass() != obj.getClass()) {
return false;
}
return this.instrument_token.getValue().equals(((MarketWatchEntry) obj).instrument_token.getValue());
}
@Override
public int hashCode() {
return 7 + 5 * Integer.valueOf(instrument_token.getValue());
}
}
问题出在您的 changeDataDemo
方法中:
private void changeDataDemo() {
marketWatchEntries.get(0).buyer_price = new SimpleDoubleProperty(100);
}
您正在创建属性的新实例,而不是更改它们的值。
像这样的东西有效:
private void changeDataDemo() {
marketWatchEntries.get(0).buyer_price.set(100);
}
但建议在您的实体上提供 setters/getters class:
class MarketWatchEntry extends RecursiveTreeObject<MarketWatchEntry> {
private final DoubleProperty buyer_price;
...
public MarketWatchEntry(String instrument_token, String exchange, String instrument_type, String trading_symbol,
String expiry, double buy_qty, double buy_price, double sell_price, double sell_qty) {
...
this.buyer_price = new SimpleDoubleProperty(buy_price);
...
}
public final DoubleProperty buyer_priceProperty() {
return buyer_price;
}
public final double getBuyer_price() {
return buyer_price.get();
}
public final void setBuyer_price(double value) {
buyer_price.set(value);
}
...
}
所以你可以打电话:
private void changeDataDemo() {
marketWatchEntries.get(0).setBuyer_price(100);
}