0

我正在开发一个图书馆程序,当我进行给定的连续操作时,我的书籍 JTable 中添加了一个意想不到的行。

动作是这样的:

  • 启动程序
  • 根据注释添加过滤器(我有很多过滤器,它们是从 RowFilter 继承的类,它们都与 JTable 的 RowSorter 相关联。程序的这一部分工作正常)。在初始状态下,JTable 中有 2 本书,分别是“le livre de la丛林”和“Eloge des mathématiques”。使用过滤器后,只剩下一个“Eloge des mathématiques”。另一个未显示,但仍在模型中。
  • 在 JTable 中选择剩余的书(“le livre de la丛林”)。使用调试器,我看到在单击触发的操作期间,创建了一本标题和作者为空的书。它不可见,但如果我
  • 停用所有过滤器,JTable 中现在有 3 本书。(2 前一个加上带有虚拟值的“幽灵”。)虚拟值来自保存当前字段的方法 saveChanges()。

这是程序的图片,带有功能区(北)、字段(中)和 JTable(下)。

这里

你可以看到额外的行,出乎意料。

现在,让我们看一些代码:

当我点击 JTable 的行时,我触发了这个方法:

table.getSelectionModel().addListSelectionListener(e -> {

      if (!e.getValueIsAdjusting()) {
        if (table.getSelectedRow() > -1) {

          Book book = ((TableATM) table.getModel()).getBook(table
                  .convertRowIndexToModel(table.getSelectedRow()));

          getStatesManager().getState().selectBook(book);

        }
      }
    });

这从 UnboundState 类调用 selectBook。窗口有 2 种状态:BoundState 和 UnboundState。UnboundState 在字段为空时使用。当这些字段包含一本书的数据时(例如,在互联网上使用 ISBN 进行远程搜索之后),它会立即被保存并且状态变为绑定。

在我上面谈到的搜索之后,状态与最初的状态保持一致,我的意思是 UnboundState :搜索只更改 JTable,而不更改字段。

所以,UnboundState 的 selectBook 被触发:

@Override
  public void selectBook(Book book) {
    statesManager.setBound(book);
  }

setBound 方法的目的是改变状态:

public void setBound(Book book) {
    state = new BoundState(book, this, bookWindow,
            new ChoiceISBNDialog(bookWindow));


  }

这是 setBound 调用的构造函数:

public BoundState(Book book, StatesManager statesManager,
                    BookWindow bookWindow, ChoiceISBNDialog choice) {
    this.statesManager = statesManager;
    this.bookWindow = bookWindow;
    this.choice = choice;

    SwingUtilities.invokeLater(() -> {
      statesManager.enableFields(true);
      if (statesManager.getState().getName().equals("BOUND"))
        saveChanges();
      statesManager.displayBook(book);
      statesManager.setCaretsToZero();
      bookWindow.ribbon.btn_revertChanges.setEnabled(false);
      bookWindow.ribbon.btn_storeInTable.setEnabled(false);
    });
  }

重要的是不应该调用方法 saveChanges(),因为调用 invokeLater 时的当前状态是“UNBOUND”。

但是当我调试程序时,我得到这个:方法运行,按照我给你的odrer,除了调试器不进入invokeLater,它继续,方法完成,最后一个是JTable听众。但是我在 saveChanges() 方法中放置了一个断点,我看到 saveChanges() 方法是在 JTable 的侦听器结束后触发的。这是我认为的 invokeLater 的效果。但当时,状态变为“绑定”,saveChanges 方法认为字段中的实际书籍是新的并尝试保存它。

我怎样才能让它工作?我尝试调用 invokeAndWait 但它冻结了程序(它肯定会停止,即使在 1 分钟或更长时间之后)。

4

0 回答 0