0

我有一个小型财务应用程序,它在 TableView 中显示市场数据观察列表(当前买入价/当前卖出价)。

对于我正在观看的每个符号,买入/卖出价格正在实时更新。

一切都运行得非常好,但有时我在尝试设置出价或有时设置要价时会收到 NullPointerException。

这是我的 GUI 控制器中设置 TableView 和 Columns 的片段

TableColumn<PositionRowData, Number> bidColumn = new TableColumn<PositionRowData, Number>(BID_COLUMN_NAME);
TableColumn<PositionRowData, Number> askColumn = new TableColumn<PositionRowData, Number>(ASK_COLUMN_NAME);
TableColumn<PositionRowData, Number> lastColumn = new TableColumn<PositionRowData,Number>(LAST_COLUMN_NAME);
.
.
.
   //and later on the column is initialized like this
bidColumn.setCellFactory(new USDTableCellRenderer());
bidColumn.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<PositionRowData,Number>, ObservableValue<Number>>() {
        @Override
        public ObservableValue<Number> call(
                CellDataFeatures<PositionRowData, Number> arg0) {
            return arg0.getValue().getBid();
        }
   });

//finally the columns are added to the table
TableView.getColumns().addAll(....bidColumn..etc);

这是我的 PositionRowData 构造函数的一个片段,其中包含初始化:

bid = new SimpleDoubleProperty();
ask = new SimpleDoubleProperty();

这是我的设置器代码的样子:

public void setBid(double bid) {
    try {
        this.bid.set(bid);
    } catch (NullPointerException e) {
        _log.error("Would have been NPE in setBid. trying to set new value: "+bid);
    }
}
  • 顺便说一句 - 抓住我的 NPE 不是我通常的习惯!我只是把它卡在那里,因为我希望为我测试这个的人提供一个更优雅的错误!

这是完整的堆栈跟踪:

2013-06-20 11:56:12,500 ERROR [DataChannel Reader Thread] - NPE
java.lang.NullPointerException
at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(Unknown Source)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(Unknown Source)
at javafx.beans.property.DoublePropertyBase.fireValueChangedEvent(Unknown Source)
at javafx.beans.property.DoublePropertyBase.markInvalid(Unknown Source)
at javafx.beans.property.DoublePropertyBase.set(Unknown Source)
at com.eak070.ui.tablemodel.PositionRowData.setAsk(PositionRowData.java:86)
at com.eak070.ui.ETGUIController.onQuote(ETGUIController.java:808)
at com.eak070.ui.ETGUIController$24.handleDataChannelMessage(ETGUIController.java:737)
at com.eak070.communication.stream.DataChannel.processDataChannelMessage(DataChannel.java:211)
at com.eak070.communication.stream.DataChannel.readFromSocketChannel(DataChannel.java:156)
at com.eak070.communication.stream.DataChannel.access$1(DataChannel.java:122)
at com.eak070.communication.stream.DataChannel$1.run(DataChannel.java:99)

我不太确定发生了什么,因为我对 JavaFX 还有些陌生,并不真正了解绑定的来龙去脉。

这似乎偶尔发生。换句话说,我还不能故意复制它。它只是看似随机发生。

这感觉可能是一个线程问题,但我只是不确定为什么 set() 方法内部有一个 NPE,因为该表中的行没有被破坏。一旦创建了行,它们就会永远存在。任何建议/想法表示赞赏。

4

2 回答 2

0

当我看到你的代码片段时......你使用

new SimpleDoubleProperty() 

并且您永远不会设置要设置的 bean 和属性名称。我猜它确实调用了 NullPointerException,但不是因为值(双重 -> 双重转换),而是因为您没有设置 bean 或属性名称。

于 2013-06-20T21:52:38.483 回答
0

不确定它是否仍然相关,但我刚刚在我的应用程序中遇到了同样的事情,答案正如彼得劳里所说 - 仅使用 Platform.runLater() 在事件线程上调用 set 方法

于 2013-12-10T11:39:25.437 回答