JavaFX:将textProperty从标签绑定到ObservableList的大小

JavaFX:将textProperty从标签绑定到ObservableList的大小,java,binding,javafx-2,javafx,javabeans,Java,Binding,Javafx 2,Javafx,Javabeans,我对FX是新手,对Java不是很陌生,所以请耐心听我说!我所拥有的是一个简单的应用程序,它使用一个由ObservableList支持的JavaFXTableView 当我第一次启动应用程序时,我会生成另一个线程(从应用程序的start方法)来侦听对日志文件的更改,并向observeList添加另一个元素,以便该行在TableView中立即可见。我认为在窗口中有一个包含可观察列表当前大小的标签是有益的。我正在尝试将标签的textProperty绑定到ObservableList的大小。我的第一次尝

我对FX是新手,对Java不是很陌生,所以请耐心听我说!我所拥有的是一个简单的应用程序,它使用一个由ObservableList支持的JavaFXTableView

当我第一次启动应用程序时,我会生成另一个线程(从应用程序的start方法)来侦听对日志文件的更改,并向observeList添加另一个元素,以便该行在TableView中立即可见。我认为在窗口中有一个包含可观察列表当前大小的标签是有益的。我正在尝试将标签的textProperty绑定到ObservableList的大小。我的第一次尝试产生了:

tableSizeLabel.textProperty().bind(Bindings.size((tableView.getItems()).asString())

但我相信我误解了绑定API。我意识到observeList.size()返回一个常规int而不是observeValue,这是它工作所必需的,但是我认为Bindings类有一个静态方法来为我创建一个

后端模型包含作为静态变量的列表(我省略了listenforchanges部分):

控制器类:

public class TableDisplayController implements Initializable {

@FXML
private TableView<SNMPTrap> tableView;
@FXML
private Label tableSizeLabel;

@Override
public void initialize(URL url, ResourceBundle rb) {

    tableView.setItems(LogFileListener.getModel());

    tableSizeLabel.textProperty().bind(Bindings.size((tableView.getItems())).asString());

}
公共类TableDisplayController实现可初始化{
@FXML
私有TableView TableView;
@FXML
私有标签tableSizeLabel;
@凌驾
公共void初始化(URL、ResourceBundle rb){
setItems(LogFileListener.getModel());
tableSizeLabel.textProperty().bind(Bindings.size((tableView.getItems()).asString());
}
这在FX中可能吗?我是否需要在整个ObservableList中添加一个更改侦听器,然后用getSize()更新标签


提前感谢!

您的绑定语句对于您想要实现的目标是正确的(将标签的文本属性绑定到可观察列表的大小)

您的代码存在并发问题。将发生的情况是LogFileListener在其自己的线程中运行,更新项目列表,并且项目在LogFileListener线程中更新,从而触发JavaFX应用程序线程之外的场景图更新。这是一件“坏事”,因为JavaFX使用单个GUI线程

您需要做的是确保绑定触发器和表项更新只发生在JavaFX应用程序线程上(并且您可能需要以一种高效的方式这样做,这样您就不会因为太多的小更新调用而使JavaFX事件处理器过载)

当前解决方案的一个简单修复方法是使用以下代码

final SNMPTrap trap = parseTrap(line);
Platfrom.runLater(new Runnable() {
  @Override public void run() {
    model.add(trap);
  }
});
您的应用程序可能会从更复杂的方法中受益。您可以在Platform.runLater、任务、服务和主题中搜索StackOverflow相关问题,还可以查看有关JavaFX和中并发性的Oracle文档,以更好地了解所有这些内容的工作原理以及您的选项

public class TableDisplayController implements Initializable {

@FXML
private TableView<SNMPTrap> tableView;
@FXML
private Label tableSizeLabel;

@Override
public void initialize(URL url, ResourceBundle rb) {

    tableView.setItems(LogFileListener.getModel());

    tableSizeLabel.textProperty().bind(Bindings.size((tableView.getItems())).asString());

}
final SNMPTrap trap = parseTrap(line);
Platfrom.runLater(new Runnable() {
  @Override public void run() {
    model.add(trap);
  }
});