【问题标题】:Is there any way to add objects to a JComboBox and assign a String to be shown?有没有办法将对象添加到 JComboBox 并分配要显示的字符串?
【发布时间】:2013-11-22 21:49:47
【问题描述】:

我想向 JComboBox 添加对象,但在 JComboBox 上为每个对象显示一个字符串。

例如在下面的html代码中

<select>
  <option value="1">Item 1</option>
  <option value="2">Item 2</option>
  <option value="3">Item 3</option>
  <option value="4">Item 4</option>
</select>

在第一项中,显示的String是“Item 1”,但是item的值是“1”。

有没有一个表单可以用 JComboBox 做类似的事情?

【问题讨论】:

标签: java swing combobox jcombobox


【解决方案1】:

首先查看How to Use Combo Boxes,尤其是Providing a Custom Renderer

基本上,您想定义将包含在组合框中的对象...

public class MyObject {
    private String name;
    private int value;

    public MyObject(String name, int value) {
        this.name = name;
        this.value = value;
    }

    public String getName() {
        return name;
    }

    public int getValue() {
        return value;
    }
}

然后创建一个知道如何渲染它的自定义ListCellRenderer...

public class MyObjectListCellRenderer extends DefaultListCellRenderer {

    public Component getListCellRendererComponent(
                                   JList list,
                                   Object value,
                                   int index,
                                   boolean isSelected,
                                   boolean cellHasFocus) {
        if (value instanceof MyObject) {
            value = ((MyObject)value).getName();
        }
        super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        return this;
    }
}

然后填充组合框并应用单元格渲染器...

JComboBox box = new JComboBox();
box.addItem(new MyObject(..., ...));
//...
box.setRenderer(new MyObjectListCellRenderer());

同样,您可以覆盖对象的 toString 方法,但出于显示目的,我倾向于避免这样做,因为我喜欢 toString 方法来提供有关对象的诊断信息,但这就是我

【讨论】:

  • +1。除了没有覆盖toString 方法的充分理由之外,还有一个非常简单的不这样做的原因:toString 方法只能被覆盖一次,因此是一个潜在的瓶颈。这个事实就是例证here
【解决方案2】:

如果您的组合框模型包含对象,则默认使用它们的toString() 方法在组合框中显示它们。如果toString() 方法显示了你想要的,你就没有什么可做的了。

否则,您只需要设置一个单元格渲染器来自定义每个对象的显示方式(这并不限制您使用文本:您还可以更改字体、颜色、图标等)。

这在Swing tutorial中都有描述。

【讨论】:

    【解决方案3】:

    例如在下面的html代码中

    对于像这样简单的事情,如果您有“ID”、“Value”类型的数据,我确实喜欢自定义对象的方法,其生活目的是提供自定义 toString() 方法。有关此类可重用对象,请参阅 Combo Box With Hidden Data

    论坛中的许多人确实推荐自定义渲染器。不幸的是,使用自定义渲染器会破坏组合框的默认功能。有关作为解决方案的更多信息,请参阅Combo Box With Custom Renderer

    【讨论】:

      【解决方案4】:

      是的,这可以使用对象类型作为JComboBox 泛型的参数来完成,如下所示:

      public class TestFrame extends JFrame {
          // This will be the JComboBox's item class
          private static class Test {
              private Integer value;
              private String label;
      
              public Test(Integer value, String label) {
                  this.setValue(value);
                  this.setLabel(label);
              }
      
              public Integer getValue() {
                  return value;
              }
      
              public void setValue(Integer value) {
                  this.value = value;
              }
      
              public String getLabel() {
                  return label;
              }
      
              public void setLabel(String label) {
                  this.label = label;
              }
      
              // The "toString" method will be used by the JComboBox to generate the label for the item
              @Override
              public String toString() {
                  return getLabel();
              }        
          }
      
          public static void main(String[] args) {
              TestFrame frmMain = new TestFrame();
              frmMain.setSize(300, 50);
              frmMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      
              // Here you declare a JComboBox that 
              // uses the type "Test" for item elements 
              JComboBox<Test> cmbCombo = new JComboBox<TestFrame.Test>();
      
              for (int i = 0; i < 10; i++) {
                  // Add some elements for the combo 
                  cmbCombo.addItem(new Test(i, String.format("This is the item %d", i + 1)));
              }
      
              // Listen to changes in the selection
              cmbCombo.addActionListener(new ActionListener() {
                  @Override
                  public void actionPerformed(ActionEvent e) {
                      JComboBox<Test> cmbCombo = (JComboBox<Test>) e.getSource();
      
                      // The selected element is a "Test" instance, just cast it to the correct type
                      Test test = (Test) cmbCombo.getSelectedItem();
      
                      // Manipulate the selected object at will
                      System.out.printf("The selected value is '%d'\n", test.getValue());
                  }
              });
      
              frmMain.add(cmbCombo);
              frmMain.setVisible(true);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-04
        • 2013-01-04
        • 1970-01-01
        • 2020-12-31
        相关资源
        最近更新 更多