Stubborn JComboBox

I have a JComboBox shown in the code below. When a program fires its action, the Performed event fires immediately, raising some exceptions with a null pointer, so I want to start with none of the selected elements. However, for some reason it does not work (it always starts with the display of "USD / TRY", no matter what I do). Does anyone have an 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: creating a combo box as shown below does not change anything.

 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); } } 
+4
source share
3 answers

Your (incomplete) example causes

 comboBox.setSelectedIndex(0); 

right before you become visible by canceling the previous settings. Set the desired starting index before adding a listener and do not neglect the start of the EDT , as shown in 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); } } 
+7
source

1) add an ItemListener instead of an ActionListener , but this ItemListener always fired SELECTED and DESELECTED events DESELECTED ,

  myComboBox.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { //some stuff } } }); 

2) your graphical interface may or may not be created on EventDispashThread , but in this case it does not matter, you should defer this method by wraping in 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) it would be better to implement AutoCompete JComboBox / JTextField for currency pairs

4) may not matter, but CcyPairs have four sides by default.

  • Buy BaseCcy

  • Sell BaseCcy

  • Buy VariableCcy

  • Sell VariableCcy

+2
source

Suggestions are still good. But sometimes, when things are really confused as to how the components are constructed, a more direct fix is ​​required:

  • subclass of JComboBox (or any Swing class fires events, JList, etc.)
  • add field, private boolean fireEvents = false ; Think about it volatile .
  • override the appropriate fireXXX() methods to check the status of fireEvents
  • sets only fireEvents = true after completion of construction and initialization
  • If you need "overhaul", for example, when uploading a new file, new settings, you can turn fireEvents back to false when restoring everything.
0
source

Source: https://habr.com/ru/post/1389310/


All Articles