2012-01-04 1 views
4

У меня есть JComboBox, показанный в коде ниже. Когда программа запускает свое действие, событие Performed запускается немедленно, вызывая некоторые исключения с нулевым указателем, поэтому я хочу начать с ни одного из выбранных элементов. Однако по какой-то причине он не работает (он всегда начинается с отображения «USD/TRY», что бы я ни делал). У кого-нибудь есть идея?The Stubborn JComboBox

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: Создание поля со списком, как показано ниже не изменяет что-нибудь либо

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

Попробуйте загрузить строку [] после создания JComboBox? –

+0

Пробовал и не работает либо =/Я обновил вопрос соответствующим образом. спасибо – Cemre

+3

Получение стека след исключения поможет. Как вы могли добавить ActionListener в поле со списком, которое еще не создано? –

ответ

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

Спасибо. Другие ответы в какой-то степени решали проблемы, но все же были некоторые проблемы, но это полностью удалось решить. Я считаю, что главной причиной является отсутствие функции invokeLater для построения фрейма (т. Е. Начиная с EDT). – Cemre

+0

Спасибо за следующее; Меня всегда заинтриговали новые способы разоблачить проблему EDT. – trashgod

+0

@Cemre, вы когда-нибудь читали API и учебник ??? В примере из учебника правильно используется EDT, поэтому я указал вам на предыдущее учебное пособие. – camickr

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) графического интерфейса может быть, это и не будет создан на 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

+0

Большое вам спасибо за подробный ответ. Я очень ценю это. Хотя, второе предположение решило ошибку со списком, я все же получал исключения с нулевым указателем. – Cemre

+0

+1 для экспертизы предмета! – trashgod

+0

-1 для слишком много случайных пуль - с новым годом :-) – kleopatra

0

Предложения до сих пор хороши. Но иногда, когда вещи действительно запутанным о том, как компоненты получить построены, более прямой требуется исправление:

  1. подкласс JComboBox (или любой другой класс свинг стрельбы события, JList, и т.д ...)
  2. добавьте поле, private boolean fireEvents = false; Подумайте об этом volatile.
  3. переопределяют соответствующие fireXXX() методы проверки состояния fireEvents
  4. только набор fireEvents = true после всего строительства и завершения инициализации
  5. если «капитальный ремонт» позже призвал, например, при загрузке нового файла, новый настройки, вы можете включить fireEvents в false при восстановлении всего.
+0

Спасибо за ваш ответ. – Cemre

+0

-1 _when вещи действительно convoluted_ это в основном потому, что код приложения делает что-то неправильно. Поэтому вместо случайного неприличного подкласса, странных флагов или переохлаждений переопределения первым шагом является выкапывание и понимание того, что именно идет не так в конкретном контексте, и исправить _that_ – kleopatra