2016-07-18 253 views
0

我有一个Java应用程序用于运行锦标赛,其中我建立了一个自动建议功能,从数据库获取名称并将其显示在JPopupMenu中。我一直无法按需复制这个bug,但偶尔有一个JPopupMenus会像平常一样消失,只不过它的位置轮廓仍然在屏幕上,并且显示在所有其他程序甚至包括其他程序上如果我的应用程序最小化。JPopupMenu不会消失,因为它应该

以下是我在谈论的一个截图: enter image description here

你可以看到下面“埃斯皮诺萨” JPopupMenu的一些残余仍然被显示出来。这有时包含文本内部和其他时间只是在一个空框中的背景颜色。这种残留物是纯粹的化妆品,我还没有找到任何物理或编程方式与其进行交互的方式(热编码)。

这里是我用来显示JPopupMenu的方法:

private void resetLastNamePopup() { 

    Thread t = new Thread() { 

     @Override 
     public void run() { 

      lnPopup.setVisible(false); 
      lnPopup.removeAll(); 

      if(DBHSDatabaseIntermediary.isConnected()) { 

       if(!(fnTextField.getText().equals("") && lnTextField.getText().equals(""))) { 

        JMenuItem item = null; 
        String[] names = DBHSDatabaseIntermediary.getLastNames(fnTextField.getText(), lnTextField.getText()); 
        for(int i=0; i < names.length; i++) { 

         if(!names[i].equals(lnTextField.getText().trim())) { 

          item = new JMenuItem(names[i]); 
          item.addActionListener(lnActionListener); 
          item.addMouseListener(NewPlayerPanel.this); 
          lnPopup.add(item); 

         } 

        } 

        if(names.length > 0 && !names[0].equals("")) { 

         lnPopup.setVisible(true); 

        } 
        lnPopup.grabFocus(); 

       } 

      } 

     }// ends run() 

    }; 

    t.start(); 

} 

预先感谢您。

回答

3

必须在AWT事件分派线程上调用Swing方法和构造函数。您正在另一个线程上调用这些方法。其结果是“未定义的行为” - 通常意味着事情有时会起作用,但并非总是这样。

您需要的Swing调用从数据库调用,这是使用EventQueue.invokeLater(或它的别名,SwingUtilities.invokeLater)来进行分离:

private void resetLastNamePopup() { 

    lnPopup.setVisible(false); 
    lnPopup.removeAll(); 

    final String fn = fnTextField.getText(); 
    final String ln = lnTextField.getText(); 

    Thread t = new Thread() { 

     @Override 
     public void run() { 
      if(DBHSDatabaseIntermediary.isConnected() 
        && !fn.isEmpty() && !ln.isEmpty()) { 

       final String[] names = 
        DBHSDatabaseIntermediary.getLastNames(fn, ln); 

       // Rebuild JPopupMenu in AWT event thread. 
       EventQueue.invokeLater(new Runnable() { 
        @Override 
        public void run() { 
         for (String name : names) { 
          if (!name.equals(ln)) { 
           JMenuItem item = new JMenuItem(name); 
           item.addActionListener(lnActionListener); 
           lnPopup.add(item); 
          } 
         } 

         if (names.length > 0 && !names[0].isEmpty()) { 
          lnPopup.setVisible(true); 
          lnPopup.grabFocus(); 
         } 
        } 
       }); 
      } 
     }// ends run() 

    }; 
    t.start(); 
} 

欲了解更多信息,请参阅javax.swing package contract,并在Java教程Concurrency in Swing

相关问题