我遇到了JComboBox
和JOptionPane
对话框的问题。
情况是这样的:
我有一个包含初始数据的JComboBox,我有一个ActionListener
,在选择时会显示一个JOptionPane
对话框,其中包含有关重新验证的警告。
当进行选择时,对话框显示为正常但JComboBox
未完成循环并保持JComboBox
打开,直到单击对话框,然后您需要再次单击以执行选择一个选项(无论第一次点击是否在按钮顶部)。
import javax.swing.JPanel;
import java.awt.Frame;
import java.awt.BorderLayout;
import javax.swing.JDialog;
import javax.swing.JComboBox;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class DialogFocus extends JDialog {
private static final long serialVersionUID = 1L;
private JPanel jContentPane = null;
private JComboBox jComboBox = null;
public static void main(String[] args) {
new DialogFocus(null);
}
/**
* @param owner
*/
public DialogFocus(Frame owner) {
super(owner);
initialize();
setLookAndFeel();
this.setVisible(true);
}
public void setLookAndFeel() {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* This method initializes this
*
* @return void
*/
private void initialize() {
this.setSize(300, 200);
this.setContentPane(getJContentPane());
}
/**
* This method initializes jContentPane
*
* @return javax.swing.JPanel
*/
private JPanel getJContentPane() {
if (jContentPane == null) {
jContentPane = new JPanel();
jContentPane.setLayout(new BorderLayout());
jContentPane.add(getJComboBox(), BorderLayout.CENTER);
}
return jContentPane;
}
/**
* This method initializes jComboBox
*
* @return javax.swing.JComboBox
*/
private JComboBox getJComboBox() {
if (jComboBox == null) {
String[] items = {"1", "2", "3", "4", "5"};
jComboBox = new JComboBox(items);
jComboBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
showDialog();
}
});
}
return jComboBox;
}
protected void showDialog() {
JOptionPane.showMessageDialog(this, "Selection made");
}
}
我使用的代码非常复杂,所以我在这里汇总了一个基本的代码示例。通过设置外观,只需单击2次即可点击有效选项,但如果没有它,则只需单击一下即可。 (在构造函数中注释掉setLookAndFeel()
)。
有没有人有任何想法如何解决这个问题,以确保无论外观如何都只需要点击一次?
提前致谢
答案 0 :(得分:1)
将代码包装在invokeLater中,让组合框在显示对话框之前自行重绘:
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
showDialog();
}
});
答案 1 :(得分:0)
从内部类来看,要访问外部类中的变量,需要引用ComboBox.this.myBool。通常情况下,如果它是明确的,你可以做myBool。
public class ComboBox {
private boolean myBool = false;
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
boolean myBoolAgain = ComboBox.this.myBool;
showDialog();
}
});
}
答案 2 :(得分:0)
在为JComboBox实现ItemListener时遇到了类似的问题,如果满足特定条件,它将在ItemEvent.DESELECTED事件之后向用户询问问题。由于ItemListener实现可能会根据用户的回答恢复选择,因此,将新的Runnable分配给EDT并不是一种选择-带有问题的JOptionPane需要显示在ItemListener中,这表明了所描述的问题OP。
即使创建并显示了后续的模态对话框,JComboBox的弹出窗口也会在显示时保持焦点,因此您需要使用JComboBox.hidePopup()
在显示JOptionPane之前将其隐藏。这样做可以使所显示的对话框焦点集中在预期的位置,而无需双击。