hope you can help.
I'm hoping this isn't just a bug and that we can solve it.
I currently have a Java program with a JComboBox
. When the user changes the selected item in the combo box a JOptionPane
appears to allow the user to confirm the change.
When the new selection is made in the combo box, the JOptionPane
appears as desired but you have to click it twice to use it. That is, click it once to gain focus and then click the button you want to use. Another method is to click within the bounds of the program's GUI (behind the optionPane) and then click the button.
No Exceptions occur, and the program functions as normal once the buttons are clicked.
This functionality only occurs using the Nimbus
LookAndFeel and not with the native macos laf (building on mac, haven't tested on windows) but I need to use nimbus for other reasons.
I've been looking through the Nimbus issue tracking but have yet to find the fault.
I have JButton which calls the SAME code (ie JOptionPane.showConfirmDialog(...
) and this works perfectly, it's just when it's called from the action of the combo box.
Really hope you can help! Cheers in advance!
import javax.swing.UIManager.*;
import javax.swing.*;
public class TestJavaProblem extends JFrame {
JComboBox jComboBox1;
public TestJavaProblem() {
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
initComponents();
}
private void initComponents() {
jComboBox1 = new JComboBox();
//give it some values
jComboBox1.setModel(new DefaultComboBoxModel(new String[] { "1", "2"}));
//add listener
jComboBox1.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) { fireTask(evt);}
});
this.add(jComboBox1);
pack();
}
private void fireTask(java.awt.event.ItemEvent evt) {
if (evt.getStateChange() == 1) { //so dialog fires only once
int i = JOptionPane.showConfirmDialog(jComboBox1, "Message Text", "Title", JOptionPane.OK_CANCEL_OPTION);
System.out.println("Result:" + i);
}
}
public static void main(String args[]) {
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {/*no nimbus*/}
new TestJavaProblem().setVisible(true);
}
}
don't use magic number,
if (evt.getStateChange() == 1) { //so dialog fires only once
or
int i = JOptionPane.showConfirmDialog(jComboBox1,
here is workaround code, but seems like required for MetalLookAndFeel, Substance on Windows OS
import javax.swing.UIManager.*;
import javax.swing.*;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
public class TestJavaProblem extends JFrame {
private static final long serialVersionUID = 1L;
private JComboBox jComboBox1;
private boolean boloComboBox = false;
public TestJavaProblem() {
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
initComponents();
}
private void initComponents() {
jComboBox1 = new JComboBox();
jComboBox1.setModel(new DefaultComboBoxModel(new String[]{"1", "2"}));
jComboBox1.addItemListener(new java.awt.event.ItemListener() {
@Override
public void itemStateChanged(final java.awt.event.ItemEvent evt) {
if (jComboBox1.isPopupVisible()) {
jComboBox1.setPopupVisible(false);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
fireTask(evt);
}
});
}
}
});
jComboBox1.addPopupMenuListener(new PopupMenuListener() {
@Override
public void popupMenuCanceled(PopupMenuEvent e) {
System.out.println(e.getSource());
}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
System.out.println(e.getSource());
}
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
System.out.println(e.getSource());
}
});
add(jComboBox1);
pack();
}
private void fireTask(java.awt.event.ItemEvent evt) {
if (evt.getStateChange() == 2) {
int i = JOptionPane.showConfirmDialog(jComboBox1,
"Message Text", "Title", JOptionPane.OK_CANCEL_OPTION);
System.out.println("Result:" + i);
}
}
public static void main(String args[]) {
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TestJavaProblem().setVisible(true);
}
});
}
}