我在下面的代码中显示了一个JComboBox。当程序启动时,actionPerformed事件立即触发,导致一些空指针异常,所以我想从没有选择的元素开始。但是,由于某些原因它不起作用(无论我做什么,它始终以显示“USD / TRY”开头)。任何人都有任何想法?
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
更新:构建如下所示的组合框不会改变任何内容
JComboBox comboBox = new JComboBox();
comboBox.addItem("USD/TRY");
comboBox.addItem("EUR/TRY");
comboBox.addItem("GBP/TRY");
这是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);
}
}
答案 0 :(得分:7)
您的(不完整)示例调用
comboBox.setSelectedIndex(0);
在变为可见之前,取消之前的任何设置。在添加监听器之前设置所需的初始索引,并且不要忽略从EDT开始,如下面的sscce所示。
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);
}
}
答案 1 :(得分:2)
1)添加ItemListener而不是ActionListener
,但此ItemListener
总是会触发两次事件SELECTED
和DESELECTED
,
myComboBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
//some stuff
}
}
});
2)您的GUI可能在EventDispashThread上创建,但在这种情况下并不重要,您必须通过包装到invokeLater()中来延迟此方法,例如
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)更好的是货币对的实施AutoCompete JComboBox / JTextField
4)也许并不重要,但CcyPairs默认有四个方面
Buy BaseCcy
Sell BaseCcy
Buy VariableCcy
Sell VariableCcy
答案 2 :(得分:0)
到目前为止的建议都很好。但有时候,如果对构建组件的方式感到困惑,则需要更直接的修复:
private boolean fireEvents = false
;考虑将其volatile
。fireXXX()
方法以检查fireEvents的状态fireEvents = true