JPopupMenu 没有像它应该的那样消失
JPopupMenu doesn't disappear like it should
我有一个用于 运行 锦标赛的 Java 应用程序,我在其中构建了一个自动建议功能,该功能从数据库中获取名称并将它们显示在 JPopupMenu 中。我无法按需复制此错误,但有时 JPopupMenus 中的一个会像往常一样消失,除了它所在位置的轮廓仍在屏幕上并显示在所有内容上,甚至包括其他程序如果我的应用程序被最小化。
这是我正在谈论的内容的屏幕截图:
您可以看到在 "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();
}
提前致谢。
必须在 AWT 事件分派线程上调用 Swing 方法和构造函数。您正在不同的线程上调用这些方法。结果是“未定义的行为”——这通常意味着事情有时会奏效,但并非总是如此。
您需要将 Swing 调用与数据库调用分开,这是使用 EventQueue.invokeLater (or its alias, 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 contract, and Concurrency in Swing。
我有一个用于 运行 锦标赛的 Java 应用程序,我在其中构建了一个自动建议功能,该功能从数据库中获取名称并将它们显示在 JPopupMenu 中。我无法按需复制此错误,但有时 JPopupMenus 中的一个会像往常一样消失,除了它所在位置的轮廓仍在屏幕上并显示在所有内容上,甚至包括其他程序如果我的应用程序被最小化。
这是我正在谈论的内容的屏幕截图:
您可以看到在 "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();
}
提前致谢。
必须在 AWT 事件分派线程上调用 Swing 方法和构造函数。您正在不同的线程上调用这些方法。结果是“未定义的行为”——这通常意味着事情有时会奏效,但并非总是如此。
您需要将 Swing 调用与数据库调用分开,这是使用 EventQueue.invokeLater (or its alias, 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 contract, and Concurrency in Swing。