简体   繁体   English

Java Swing线程问题

[英]Java Swing Threading Problem

so here's the problem. 这就是问题所在。 I have a JDialog box that consists of 3 combo boxes, a text field, a few buttons and a JTable. 我有一个JDialog框,它由3个组合框,一个文本字段,一些按钮和一个JTable组成。 The JTable information is filtered based on the text field and combo boxes, so for instance it starts with all of the data and gets shrunk down to only the data that starts with any string value the user decides. JTable信息是根据文本字段和组合框进行过滤的,因此,例如,它以所有数据开头,并且缩减为仅以用户决定的任何字符串值开头的数据。

What's happening though is that while the values filter correctly, if I click in the JTable (in the white space, where there are no rows) then the rows that were deleted show up, like they were invisible until I clicked on them. 但是,发生的是,尽管值正确过滤,但是如果我单击JTable(在空白处,没有行),则将显示被删除的行,就像它们在我单击它们之前是不可见的。 I've tried almost everything: I've tried re-creating the table every time filter is clicked (bad hack that didn't even work), I've called all of the repaint, revalidate, firechanged methods, I rewrote the dialog from scratch to make sure I didn't do any stupid mistakes (if I made one I didn't find it at least), and I've tried putting them on separate threads. 我已经尝试了几乎所有方法:每次尝试单击过滤器时我都尝试重新创建表(坏的技巧甚至都无效),我调用了所有的重绘,重新验证,firechanged方法,我重写了对话框从头开始,以确保我没有犯任何愚蠢的错误(如果我犯了一个错误,至少没有找到它),并且我尝试将它们放在单独的线程中。 The only fix I haven't tried is using a swing worker, but that's because my filtering was a little too complicated for me to figure out what goes where and how to extend the swing worker correctly. 我没有尝试过的唯一解决方法是使用Swing工作者,但这是因为我的筛选工作太复杂了,以至于我无法确定要去哪里以及如何正确扩展Swing工作者。 The GUI is generated by netbeans (bleh), and has worked in my other dozen or so JDialogs just fine (perfectly in fact). 该GUI是由netbeans(bleh)生成的,并且在我的其他十几个JDialogs中都可以正常工作(实际上是完美的)。 Here's the method that doest the filtering, if any of you can help it would be greatly appreciated. 这是不进行过滤的方法,如果可以帮助您,将不胜感激。

 private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {

        nameFilter = "task1";
        javax.swing.table.DefaultTableModel dm = (javax.swing.table.DefaultTableModel)jTable1.getModel();


       tempParameters = parameters;
       String currentString;
       int rowNumber = 0;
       while (dm.getRowCount()>rowNumber){
           currentString = (String)(jTable1.getValueAt(rowNumber,1));
           if(!nameFilter.equalsIgnoreCase(currentString.substring(0,nameFilter.length()))){
               dm.removeRow(rowNumber);
               parameters--;
           }
           else rowNumber++;
       }
       parameters = numOfRows;
}

Update, I also implemented the filter from the comment below, and while it filtered out the correct data, it had the exact same problem. 更新中,我还从下面的注释中实现了过滤器,尽管它过滤出了正确的数据,但也存在完全相同的问题。 In the future I will probably use this filter feature though, so thanks. 将来我可能会使用此过滤器功能,所以谢谢。

Another update, the code is still failing even after removing everything but this chunk, and all (at least I believe..) I am doing here is doing a simple remove row call. 另一个更新是,即使删除了除此块以外的所有内容,代码仍然失败,并且我在这里所做的所有操作(至少是我相信..)都是在进行简单的删除行调用。 Hope this helps a bit. 希望这个对你有帮助。

Have you tried creating a new Model every time you want to filter, instead of clearing it by deleting rows? 您是否尝试过在每次要过滤时创建一个新模型,而不是通过删除行来清除它? Create new model, copy relevant rows to new Model, set new Model in table. 创建新模型,将相关行复制到新模型,在表中设置新模型。 Really shouldn't be necessary, but it might be a quick fix. 确实没有必要,但这可能是一个快速修复。

Also, I really have to wonder why you're calling toLowerCase on two strings when you're using equalsIgnoreCase to compare them. 另外,我真的想知道为什么在使用equalsIgnoreCase比较两个字符串时为什么要在两个字符串上调用toLowerCase。

So long as this method is called from the EDT I don't think there would be a threading problem. 只要从EDT调用此方法,我认为就不会出现线程问题。 Try using 尝试使用

SwingUtilties.isEventDispatchThread()

to make sure. 确保;确定。

If you look at the API for DefaultTableModel, updates are being sent to your JTable which will repaint itself, so I don't think that is the problem. 如果您查看用于DefaultTableModel的API,更新将被发送到您的JTable,它将重新绘制自身,因此我认为这不是问题。

I would guess that it is a logic problem. 我猜这是一个逻辑问题。 If you can extract the logic into separate methods it will be easier to test and verify whether it is updating the model as you expect. 如果可以将逻辑提取到单独的方法中,则将更容易测试和验证它是否正在按预期更新模型。

Couple of observations: 几个观察:

  • If the filter happens to be larger than the string content of the row, it'll throw in the substring call 如果过滤器恰好大于该行的字符串内容,它将引发子字符串调用
  • Calling the dm.removerow is generating a bunch of tablerowsdeleted events. 调用dm.removerow会生成一堆tablerowsdeleted事件。
  • You're asking for a rowcount from the model, yet are getting the value through the table (a little inconsistent, if the model gets wrapped around another model you might be acting upon different rows), so instead of jtable1.getvalueat, use the dm.getvalueat. 您正在从模型中请求行计数,但是正在通过表获取值(有些不一致,如果模型被另一个模型包裹,则可能作用于不同的行),因此请使用jtable1.getvalueat代替dm.getvalueat。

    I think what might be happening is that as the events get fired I see there are repaint and revalidate events fired in the JTable, these can be trampling over each other as they get enqueued in the EDT. 我认为可能发生的情况是,随着事件被触发,我看到JTable中触发了重新绘制和重新验证事件,当它们被排入EDT时,它们可能会相互踩踏。

    What I would suggest is to create a new datamodel, add the rows that you want to keep, and then reassign it to your jTable1.setModel(newDm); 我建议创建一个新的数据模型,添加要保留的行,然后将其重新分配给jTable1.setModel(newDm);。

    Also to watch for is if someone else is modifying the model while you're in your eventlistener. 同样要注意的是,当您处于事件监听器中时,是否有人在修改模型。

    Hope this helps 希望这可以帮助

  • 声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

     
    粤ICP备18138465号  © 2020-2024 STACKOOM.COM