Reputation: 18754
I have a JComboBox shown in the code below. When the program starts its actionPerformed event fires up immediately causing some null pointer exceptions so I want to start with none of the elements selected. However, for some reason it does not work (it always start with displaying "USD/TRY" whatever I do). Anyone has any idea ?
JComboBox comboBox = new JComboBox(new String[]{"USD/TRY", "EUR/TRY", "GBP/TRY"});
comboBox.setSelectedIndex(-1); // doesnt change anything
comboBox.setSelectedIndex(2); // doesnt change anything
comboBox.setSelectedItem(null); // doesnt change anything
UPDATE: Building the combo box like below doesnt change anything either
JComboBox comboBox = new JComboBox();
comboBox.addItem("USD/TRY");
comboBox.addItem("EUR/TRY");
comboBox.addItem("GBP/TRY");
Here is the SSCCE:
public class MainFrame {
private final JTextArea textArea = new JTextArea();
private IExchangeSource s;
public MainFrame(final IExchangeSource s) {
//build gui
final JComboBox comboBox = new JComboBox();
comboBox.addItem("USD/TRY");
comboBox.addItem("EUR/TRY");
comboBox.addItem("GBP/TRY");
comboBox.setSelectedIndex(-1); // doesnt change anything
//comboBox.setSelectedIndex(2); // doesnt change anything
JFrame f = new JFrame("Currency Converter");
JPanel p = new JPanel(new BorderLayout());
textArea.setName("textarea");
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
this.s = s;
comboBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String exchange = (String) comboBox.getSelectedItem();
s.getData(exchange);
}
});
p.add(comboBox, BorderLayout.NORTH);
p.add(textArea, BorderLayout.CENTER);
f.setPreferredSize(new Dimension(300, 300));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.add(p);
comboBox.setSelectedIndex(0);
f.setVisible(true);
}
}
Upvotes: 4
Views: 4230
Reputation: 205775
Your (incomplete) example invokes
comboBox.setSelectedIndex(0);
right before becoming visible, canceling any previous setting. Set the desired initial index before adding the listener, and don't neglect to start on the EDT, as shown in the sscce below.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class MainFrame {
private final JTextArea textArea = new JTextArea();
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new MainFrame();
}
});
}
public MainFrame() {
//build gui
final JComboBox comboBox = new JComboBox();
comboBox.addItem("USD/TRY");
comboBox.addItem("EUR/TRY");
comboBox.addItem("GBP/TRY");
JFrame f = new JFrame("Currency Converter");
JPanel p = new JPanel(new BorderLayout());
textArea.setName("textarea");
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
comboBox.setSelectedIndex(-1);
comboBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(comboBox.getSelectedItem() + ": " + e);
}
});
p.add(comboBox, BorderLayout.NORTH);
p.add(textArea, BorderLayout.CENTER);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setSize(new Dimension(300, 300));
f.add(p);
f.setVisible(true);
}
}
Upvotes: 7
Reputation: 15729
The suggestions so far are good. But sometimes, when things are really convoluted on how Components get constructed, a more direct fix is needed:
private boolean fireEvents = false
; Consider making it volatile
.fireXXX()
methods to check the status of fireEvents fireEvents = true
after all construction and initialization is completeUpvotes: 0
Reputation: 109815
1) add ItemListener instead of ActionListener
, but this ItemListener
always fired twice events SELECTED
and DESELECTED
,
myComboBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
//some stuff
}
}
});
2) your GUI maybe is or isn't created on EventDispashThread, but in this case doesn't matter, you have to delay this method by wraping into invokeLater(), for example
public class MainFrame {
.
.
.
f.setPreferredSize(new Dimension(300, 300));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.add(p);
comboBox.setSelectedIndex(0);
f.setVisible(true);
selectDesiredItem();
}
private void selectDesiredItem() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
comboBox.setSelectedIndex(-1);
}
});
}
3) better would be implements AutoCompete JComboBox / JTextField for Currency Pairs
4) maybe not important but CcyPairs have got four sides by default
Buy BaseCcy
Sell BaseCcy
Buy VariableCcy
Sell VariableCcy
Upvotes: 2