无法使用 Renderer 将 Object 实例设置为 JComboBox 的选定项

Unable to set Object instance as selected item of JComboBox with Renderer

我有一个 DAOImplementation class,其方法定义如下。

@Override
    public Registration getRegistrationInfoById(int aRegistrationId) {
        String SQL = "{CALL getRegistrationInfoById(?)}";
        Registration aRegistration = new Registration();
        try (Connection con = DBUtil.getConnection(DBType.MYSQL);
                CallableStatement cs = con.prepareCall(SQL);) {
            cs.setInt(1, aRegistrationId);
            try (ResultSet rs = cs.executeQuery();) {
                while (rs.next()) {

                    int gradeLevel = Integer.parseInt(rs.getString(RegistrationTable.GRADELEVEL));
                    aRegistration.setGradeLevel(gradeLevel);
                }
            }
        } catch (SQLException e) {
            JOptionPane.showMessageDialog(null, e.getErrorCode() + "\n" + e.getMessage());
        }
        return aRegistration;

    }//end of method

这个 returns Grade Level 的整数值(1,2,3,4,5,6,7...等等...)我已经验证过,因为我尝试打印aRegistration.getGradeLevel();

返回的输出

现在我的问题是 JComboBox。我为我的 JComboBox 设置了一个 ListCellRenderer,它包含所有 GradeLevel

public class JComboBoxRenderer_GradeLevel extends JLabel implements ListCellRenderer<Object> {

    public JComboBoxRenderer_GradeLevel() {
        this.setOpaque(true);
    }

    @Override
    public Component getListCellRendererComponent(JList<? extends Object> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        if (value instanceof GradeLevel) {
            this.setText("" + ((GradeLevel) value).getGradelevel());
        } else {
            this.setText("--");
        }

        if (isSelected) {
            this.setBackground(Color.YELLOW);
            this.setForeground(list.getSelectionForeground());
        } else {
            this.setBackground(list.getBackground());
            this.setForeground(list.getForeground());
        }
        return this;
    }
}

并且看起来像预期的那样 JComboBox。 (GradeLevel 模型被​​渲染为简单地显示 gradelevel 的 int 值),((GradeLevel) value).getGradelevel());returns 一个整数值。

我知道即使 JComboBox 的渲染器使用 ((GradeLevel)value).getGradeLevel() 显示 GradeLevel 的整数值,JComboBox 上的实际值仍然被处理作为 GradeLevel 或对象的实例。但不是 Stringint.

所以我的问题是当我尝试将选定值设置为 int 值时,它不会更改 JComboBox 的选定值。当我使用 setSelectedItem();

时没有任何反应

这是我尝试为 GUI 做的。

//Grade Level
    GradeLevelDaoImpl gldi = new GradeLevelDaoImpl();
    List<GradeLevel> gradeLevels = gldi.getAllGradeLevelsInfo();
    DefaultComboBoxModel gradeLevelModel = new DefaultComboBoxModel(gradeLevels.toArray());
    jcmbGradeLevel.setModel(gradeLevelModel);
    jcmbGradeLevel.setRenderer(new JComboBoxRenderer_GradeLevel());
    jcmbGradeLevel.setSelectedIndex(-1);

GradeLevel gradeLevel = new GradeLevel();
gradeLevel.setGradelevel(registration.getGradeLevel());
jcmbGradeLevel.setSelectedItem(gradeLevel); //PROBLEM HERE, it doesn't change

JOptionPane 显示这个。

JOptionPane.showMessageDialog(null,"GradeLevel: "+gradeLevel);

JOptionPane.showMessageDialog(null,"GradeLevel: "+gradeLevel.getGradeLevel());

它似乎无法比较我试图将其设置为 (gradeLevel) 的对象与 JComboBox 具有的对象 (gradeLevels)。注意单数和复数。

如何操作 类型 以便 setSelectedItem()JComboBox 的类型相匹配?

谢谢。

如果您想通过使用对象的不同实例来实现这一点,但具有相同的属性,那么您需要覆盖 class 的 equalshashcode 方法, 因此组合的属性是唯一的。这是非常重要的,这是一种关系期望,即任何对象 equal 与另一个对象将具有相同的 hashcode

这是一个非常简单的示例,我在 IDE 的自动生成过程中使用了它(因为我很懒),但是,如果您的 Registration class 具有其他属性与 class 的实例进行比较时应考虑到这一点,您需要对其进行修改以支持它们(同样,任何好的 IDE 都应该能够做到这一点)

public class Registration {
    private int gradeLevel;

    public Registration(int gradeLevel) {
        this.gradeLevel = gradeLevel;
    }


    public int getGradeLevel() {
        return gradeLevel;
    }

    public void setGradeLevel(int gradeLevel) {
        this.gradeLevel = gradeLevel;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 73 * hash + this.gradeLevel;
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Registration other = (Registration) obj;
        if (this.gradeLevel != other.gradeLevel) {
            return false;
        }
        return true;
    }


}

然后使用类似...

Registration a = new Registration(1);
Registration b = new Registration(1);
Registration c = new Registration(2);

System.out.println(a.equals(b));
System.out.println(a.equals(c));
System.out.println(b.equals(c));

将打印...

true
false
false

这表明代码正在运行。

完成此设置后,您应该能够通过创建 Registration 的实例来更改所选项目,为其添加所需的属性并将其传递给 JComboBox

这是一个非常重要且非常普遍的概念,在 Java 中被大量使用,非常值得花时间学习和理解