2011-01-21 2 views
4

Код ниже имеет ошибку. После загрузки JFrame нажмите вкладку, чтобы сфокусироваться на JComboBox, и попробуйте нажать клавишу «вниз». Он ничего не делает.Nulls In JComboBox Остановка клавиши со стрелкой

Ввод нулевого значения в положение 0 вызывает это. Тем не менее, я все равно хотел бы иметь возможность выбрать Null. Я не хочу заставлять пользователя выбирать вариант.

package kobalt.test.colin; 

import java.awt.*; 
import javax.swing.*; 

public class ColinTest extends JFrame { 

    private JTextField mTextField; 
    private JComboBox mComboBox; 

    public ColinTest(){ 
     setLayout(new BorderLayout()); 

     mTextField = new JTextField("Something"); 
     mComboBox = new JComboBox(new String[]{"One", "Two"}); 
     mComboBox.insertItemAt(null, 0); //this line causes the bug 

     add(mTextField, "North"); 
     add(mComboBox, "South"); 

     pack(); 
     setVisible(true); 
    } 


    public static void main(String[] argv) { 
     new ColinTest(); 
    } 
} 

Есть ли что-то, что я могу переопределить в JComboBox, чтобы исправить это поведение?

Мне действительно не нравится вставлять пустую строку в позицию 0, так как мне придется иметь дело с этим всюду.

Использование объекта Wrapping может быть вариантом, но я предпочел бы расширить, а затем переопределить что-то в JComboBox.

ответ

2

Нулевые объекты не играют хорошо в JComboBox. Например, метод getSelectedIndex комбинированного блока, который запускается при выборе элемента, будет возвращать -1, если объект null. Могут также быть и другие методы, которые выполняют нулевые проверки и могут возвращать неверные результаты.

Но вы можете попробовать переопределить getSelectedIndex так, чтобы он возвращал 0 вместо -1, если объект имеет значение null. Также переопределите selectedItemChanged, чтобы он не проверял наличие нулей. Далее, кажется, работает, но могут быть и другие методы, которые должны быть перекрыты также:

JComboBox mComboBox = new JComboBox(new String[]{"One", "Two"}){ 
    @Override 
    public int getSelectedIndex() { 
     Object sObject = dataModel.getSelectedItem(); 
     int i,c; 
     Object obj; 

     if(sObject==null){ 
      return 0; 
     } 
     for (i=0,c=dataModel.getSize();i<c;i++) { 
      obj = dataModel.getElementAt(i); 

      if (obj != null && obj.equals(sObject)) 
       return i; 
     } 
     return -1; 
    } 

    @Override 
    protected void selectedItemChanged() { 
     fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED, 
       selectedItemReminder, 
       ItemEvent.DESELECTED)); 
     selectedItemReminder = dataModel.getSelectedItem(); 

     fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED, 
       selectedItemReminder, 
       ItemEvent.SELECTED)); 
    } 
}; 

Однако, вместо того, чтобы делать выше, я бы рекомендовал использовать объект-оболочку. Например:

class StringWrapper{ 
    final String s; 
    public StringWrapper(String s){ 
     this.s=s; 
    } 
    @Override 
    public String toString() { 
     return s; 
    } 
} 

JComboBox cb = new JComboBox(new StringWrapper[]{ 
      new StringWrapper("one"), 
      new StringWrapper("two"), 
      new StringWrapper("three")}); 
cb.insertItemAt(new StringWrapper(null), 0); 
+0

Я пошел с оберткой, спасибо. Я не был поклонником предложения «могут быть другие методы, которые тоже нужно переопределить» :) – colinjwebb

1

Создание combobox таким образом создает DefaultComboBoxModel, который основан на Vector. Поэтому значения null не могут быть вставлены. Вы можете попробовать реализовать ComboBoxModel с поддержкой нулей.

+0

-1 Это неправильно. В модель могут быть вставлены нули. Это combobox, который ведет себя по-другому, если элемент имеет значение null. – dogbane

Смежные вопросы