【问题标题】:JComboBox setSelectedItem Bug or Feature?JComboBox setSelectedItem 错误或功能?
【发布时间】:2014-04-03 14:13:06
【问题描述】:

设置选中项的原码为:

public void setSelectedItem(Object anObject) {
    Object oldSelection = selectedItemReminder;
    Object objectToSelect = anObject;
    if (oldSelection == null || !oldSelection.equals(anObject)) {

        if (anObject != null && !isEditable()) {
            // For non editable combo boxes, an invalid selection
            // will be rejected.
            boolean found = false;
            for (int i = 0; i < dataModel.getSize(); i++) {
                E element = dataModel.getElementAt(i);
                if (anObject.equals(element)) {
                    found = true;
                    objectToSelect = element;
                    break;
                }
            }
            if (!found) {
                return;
            }
        }

我认为这条线

 if (anObject.equals(element)) {

应该是

 if (element.equals(anObject)) {

考虑显示一个组合框,例如。语言 那么你有一个像

这样的类
class Language {
     String code; // eg. "en"
     String name; // eg. "English"
...
}

如果您将 Language 项添加到 ComboBox,则 toString 函数用于显示项。在上面的类中,toString 函数将返回名称。调用 setSelectedItem("en") 失败,因为

String.equals(Language) 将失败,因为 Language.toString() 将返回 "English"

反过来 Language.equals(String) 会有所帮助,因为类 Language 可以覆盖

boolean equals(String comp) {
   return comp.equals(code)
}

为了澄清,我知道如何创建一个具有所需行为的组合框,我的问题是:原始代码中的比较是一个错误还是我错过了一些基本的东西?

【问题讨论】:

    标签: java jcombobox


    【解决方案1】:

    正确实现的Object.equals是对称的,这意味着anObject.equals(element)element.equals(anObject)之间应该没有区别。

    您正在描述组合框模型包含Item 类型的对象的情况,但您想通过指定Prop 类型的对象来选择选择项目,其中Prop 的值描述了@ 的某些属性987654327@.

    使用equals() 方法的技术错误实现,您可以通过传递Prop 的实例而不是Item 来选择组合框项。

    使用原始代码,您必须在Prop 类中提供损坏的equals() 实现,并且通过您的修改,您必须在Item 类中提供损坏的equals() 实现。如果Prop 是某个库类(如您的示例中的String),那么前一种情况当然是不可能的,我认为您提出修改的原因是允许后一种情况。

    我不确定库创建者是否试图通过选择特定的anObject.equals(element) 表达式来阻止程序员实现损坏的equals(),但即使是element.equals(anObject),它仍然是不好的做法提供故意不正确的equals() 实现只是为了简化组合框选择。

    按属性执行选择的正确方法是在组合框数据中搜索具有所需属性的项目,或者创建具有所需属性的 Item 的全新实例,然后将该项目传递给 setSelectedItem .

    如果您幸运地已经使用 Java 8,那么从列表中选择所需的项目是单行的,如果没有,那么您将不得不编写一些带有循环的样板代码,但至少您将拥有正确的 @987654343 @ 执行和良心。

    【讨论】:

      【解决方案2】:

      要覆盖继承的equals方法,你应该传递一个对象作为参数而不是字符串

      public boolean equals(Object obj){
      //code goes here
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多