2017-07-07 41 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