2017-07-07 95 views
1

我有一個JComboBox,我傳遞了一個字符串數組。該數組中的某些值是多次。組合框渲染正確,但我無法選擇所有條目。JComboBox同樣條目多次

String[] entrys = {"A", "B", "C", "A"}; 
JComboBox combo = new JComboBox(entrys); 

在這個例子中,我將無法選擇第二A因爲早先已經在陣列中的A

combo.addItemListener(new ItemListener() { 
    @Override 
    public void itemStateChanged(ItemEvent e) { 
     if(e.getStateChange() == ItemEvent.SELECTED) 
      System.out.println(combo.getSelectedIndex()); 
    } 
}); 

如果我按第二A它仍然選擇第一個和印刷0

  • 什麼是最好的方式來得到這個工作?
  • 我必須編寫一個 自定義組合框模型嗎?
+0

爲什麼你在你的條目中有第二個'A'? – hamena314

+0

我只需要它爲我的用戶界面,將花費太長時間來解釋...例如它可能是一個文件名(不是完整的路徑),如果你選擇它,它會顯示一個預覽,如果它是一個圖像。 – Galveston01

回答

1

所以,基本上,JComboBoxgetSelectedIndex方法做這...

public int getSelectedIndex() { 
    Object sObject = dataModel.getSelectedItem(); 
    int i,c; 
    E obj; 

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

這就是爲什麼,當你選擇A,它的返回0,因爲它發現所選擇的值相匹配的對象在位置0。你需要生成周圍的值的唯一對象封裝,這將使比較來選擇正確的值

也許像...

public class Wrapper { 
    private final String value; 

    public Wrapper(String value) { 
     this.value = value; 
    } 

    public String getValue() { 
     return value; 
    } 

    // I personally prefer to use a custom cell renderer, but 
    // for the sake of brevity, I'm using the toString method instead 
    @Override 
    public String toString() { 
     return value; 
    } 

} 

然後,我們需要的String值映射...

String[] entrys = {"A", "B", "C", "A"}; 
Wrapper[] wrappers = Arrays.stream(entrys).map((String t) -> new Wrapper(t)).toArray(Wrapper[]::new); 
JComboBox<Wrapper> b = new JComboBox<>(wrappers); 

而且我們都設定了。請記住,當你使用getSelectedItem時,你正在處理的是Wrapper類,而不是String,所以你需要解開它們。

+0

謝謝!我已經在使用一個我可以用作包裝的類(只是沒有發佈它來保持代碼簡單),但我不知道定製單元格渲染器的可能性,我不能覆蓋這個類toString方法。我想我只是想告訴自己定製單元格渲染器以這種方式嘗試。 – Galveston01