JPopupMenu并没有像

时间:2016-07-18 19:19:34

标签: java swing jpopupmenu

我有一个用于运行锦标赛的Java应用程序,我在其中构建了一个自动建议功能,该功能从数据库中获取名称并将其显示在JPopupMenu中。我还没能按需复制这个bug,但偶尔会有一个JPopupMenus像往常一样消失,除了它的位置大纲仍在屏幕上并显示在包括其他在内的所有内容上程序,即使我的应用程序最小化。

以下是我正在谈论的内容的屏幕截图: enter image description here

你可以看到" Espinoza" 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();

}

提前谢谢。

1 个答案:

答案 0 :(得分: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();
}

有关详细信息,请参阅Java教程中的javax.swing package contractConcurrency in Swing