Динамически обновлять JComboBox (NullPointerException)

Я пытаюсь динамически обновлять JComboBox в приложении Swing и получаю исключение нулевого указателя.

class Accounts extends JPanel {

    JComboBox<String> accountSelect;
    DefaultComboBoxModel accountSelectModel;
  public Accounts() {
    this.initGUI();
  }
  public void initGUI() {
   //setLayout etc...
    String[] al = {};//start empty
   this.accountSelectModel = new DefaultComboBoxModel(al);
    this.accountSelect = new JComboBox<String>();
     this.accountSelect.setModel(accountSelectModel);
    this.add(this.accountSelect);
 }
 public void updateComboBox(String[] al) {
  //clear items and apply new
  this.accountSelectModel = new DefaultComboBoxModel(al);
  this.accountSelect.setModel(this.accountSelectModel);
 }

 public void removeComboBoxItems() {
    //A call HERE here resorts in a null exception pointer ???
    this.accountSelectModel.removeAllElements();
   }

 }

Спасибо за любой отзыв.

ОБНОВИТЬ

Разобрался с проблемой. Сначала я был уверен, что проблема не в этом (извините, что не указал этот код).

Сначала я добавлял слушателя через addActionListener (внутри учетных записей) в поле со списком accountSelect.

  this.accountSelect.addActionListener(new AcountActionListener);

class AcountSelectListener implements ActionListener {
   void actionPerformed(ActionEvent e) P
    //Object source etc..
    if(source == accountSelect) {
      //etc...
      selectAccount(item);
    }
  }

}

Вместо этого я делаю:

class Accounts extends JPanel implements ActionListener 

и переопределение метода actionPerformed внутри Accounts.

это решило мою проблему...

ОБНОВЛЕНИЕ 2

Однако я бы предпочел (а также то, что рекомендовали другие), мне не нужно создавать весь класс Accounts ActionListener.

Итак, я перешел к оригиналу и обнаружил, что проблема заключается в том, что каждый вызов this.accountSelectModel.removeAllElements запускает действие во внутреннем прослушивателе AccountSelectListener, которое добавляется к this.accountSelect.

Слушатель должен был установить новый параметр поля со списком, но поскольку он не вызывался во время изменения выбора (но при удаленииAllElements), источник объекта (элемент) был нулевым, который при передаче вызывал NPE.


person Community    schedule 04.05.2013    source источник
comment
Согласно моему обзору, ваш опубликованный код не показывает причину, по которой NPE предполагает, что его источник находится в другом месте. Давайте посмотрим код вызова, код, который вызывает метод removeComboBoxItems(). Он вызывает его для действительного экземпляра Accounts? Кроме того, рассмотрите возможность использования немного меньшего количества this. Это может сделать ваш код излишне многословным.\   -  person Hovercraft Full Of Eels    schedule 04.05.2013
comment
Да, это действительный экземпляр Accounts, на самом деле это оператор removeAllElements, вызывающий проблему, все остальное, например System.out.println и т. д., работает просто отлично. И если бы это был недопустимый экземпляр, я бы не смог вызвать updateComboBox.   -  person    schedule 04.05.2013
comment
Я предполагаю, что это может быть проблема перекраски на EDT после обновления ...   -  person    schedule 04.05.2013
comment
Исходя из фона C++, я предпочитаю использовать ключевое слово this.   -  person    schedule 04.05.2013
comment
@HovercraftFullOfEels спрашивает: Так как же это может быть null, основываясь на приведенном выше коде? Значение по умолчанию — null; Я предполагаю, что создание Accounts в начальном потоке будет участвовать в гонке слушателя, работающего на EDT. Более того, initGUI() это public и его можно вызывать в любое время.   -  person trashgod    schedule 05.05.2013
comment
проблема решена, смотрите мое обновление.   -  person    schedule 05.05.2013
comment
спасибо за помощь, все комментарии всегда указывают мне в правильном направлении.   -  person    schedule 05.05.2013
comment
Я знал, что проблема не может быть в коде, который вы изначально опубликовали, но я все еще не уверен, как только что опубликованный код вызывает проблему. Ваше решение может быть не очень хорошим, поскольку у вас не должно быть классов GUI, реализующих интерфейсы прослушивателя, если только вы не работаете над очень простой игрушечной программой, поскольку она возлагает на класс слишком большую ответственность, что может привести к слишком большой связи и недостаточной связности.   -  person Hovercraft Full Of Eels    schedule 05.05.2013
comment
У вас есть решение в таком случае?   -  person    schedule 05.05.2013
comment
@lcplusplus: невозможно сказать. Вы недостаточно хорошо определили проблему, чтобы мы могли дать решение. Вы еще не указали причину NPE. Использование внешнего класса слушателя само по себе не приводит к возникновению NPE, и на самом деле это обычно делается. Если вы создадите и опубликуете sscce, который воспроизводит вашу проблему, я на 99% уверен, что смогу показать вам достойное решение.   -  person Hovercraft Full Of Eels    schedule 05.05.2013
comment
Решил проблему (я обновил свой вопрос). Еще раз спасибо за отзыв.   -  person    schedule 05.05.2013
comment
Спасибо за обновления. 1+   -  person Hovercraft Full Of Eels    schedule 05.05.2013


Ответы (1)


Избегайте вызова общедоступных методов в конструкторе. В частности, проверьте, вызываете ли вы removeComboBoxItems() из прослушивателя, который добавляется до завершения конструктора Accounts, что может произойти, если вы не сможете создать объекты Swing GUI на поток отправки событий. По по умолчанию значение accountSelectModel равно null.

Кроме того, JComboBox прислушивается к своему ComboBoxModel, поэтому вам не нужно заменять модель; просто обновите его на месте.

person trashgod    schedule 04.05.2013
comment
Теперь я понимаю, что ваш ответ в некоторой степени касается моей проблемы с прослушивателем ComboBoxModel, хотя я не публиковал соответствующий код. Поэтому я принимаю ваш ответ со ссылкой на мое обновление 2. - person ; 05.05.2013
comment
Также отдайте должное Theodoros Chatzigiannakis и Hovercraft Full Of Eels за полезный разговор; +1 за обновление. - person trashgod; 05.05.2013