【问题标题】:Store custom object in JLabel on event在事件中将自定义对象存储在 JLabel 中
【发布时间】:2012-12-13 17:42:14
【问题描述】:

我正在将自定义对象拖放到 JLabel 中,并且能够在传输过程中引用该对象(将标签字符串更改为接收到的对象 toString),但不确定如何将自定义对象实际存储在 JLabel 中或建立参考。

在转移过程中实现此目的的最佳方法是什么?

这是接收对象并使用它来设置文本的工作传输代码(非常感谢之前的回答:here

public boolean importData(TransferSupport support) {
            boolean accept = false;
            if (canImport(support)) {
                try {
                    Transferable t = support.getTransferable();
                    Object value = t.getTransferData(PersonTransferable.PERSON_FLAVOR);
                    if (value instanceof Person) {
                        Component component = support.getComponent();
                        if (component instanceof JLabel) {
                            ((JLabel)component).setText(((Person)value).toString());
                            //action here

                        }
                    }
                } catch (Exception exp) {
                    exp.printStackTrace();
                }
            }
            return accept;
        }

JLabels 具有我想将它们存储到的特定实例变量。由于我有组件(JLabel)和值(自定义对象),我可以制作这个链接吗?

最坏的情况,我只需要为 each 标签构建一个 TransferHandler 并准确引用该值。无论如何,这可能是最佳做法吗?

【问题讨论】:

  • 为什么要将对象存储在 JLabel 中?如果您希望将 Person 与 JLabel 相关联,您可以使用 Map<JLabel, Person>,例如 HashMap,但我想您可能更愿意将 Person 放入 ArrayList 或其他集合中。
  • 我不熟悉映射,所以这可能是诀窍。
  • 与此同时,作为一个(非常草率的)解决方法,我使用 JLabel 工具提示作为参考,并使用 if 语句将工具提示与相关值匹配...我绝对需要研究映射。
  • 您存储什么信息,为什么必须将其与 JLabel 关联?如果您必须将对象与 JLabel 相关联,您只会使用 Map,但同样可能没有必要。 JLabel 用于显示信息而不是用于存储。你需要澄清你试图解决的问题,而不是你试图解决它的方式。
  • 您可以根据需要使用JComponent 方法putClientProperty()gettClientProperty()。也可以引用answer 来回答您之前关于此主题的问题。

标签: java swing


【解决方案1】:

我可以看到你有很多选择

选择 #1

创建某种Map 并将对象存储在标签上,使用标签作为键

Map<JLabel, Person> mapPeople = new HashMap<JLable, Person>(25)

然后在你的导入方法中

mapPeople.put((JLabel)component, (Person)value);

选择 #2

利用put/getClientProperty 将值存储到命名键...

在您的导入方法中...

((JLabel)component).putClientProperty("person", value);

当你再次需要它时

Person person = (Person)label.getClientProperty("person");

选择 #3

创建一个能够直接引用此人的自定义标签。

public class PersonLabel extends JLabel {
    private Person person;
    public void setPerson(Person person) {
        this.person = person;
        setText(person == null ? null : person.toString());
    }

    public Person getPerson() {
        return person;
    }
}

基本上,你会使用这个组件来代替普通的JLabel,确保你正确地转换它。

感谢气垫船和垃圾神首先提到了大部分内容。

最终选择

最终的选择取决于您自己的设计、要求以及您希望解决方案的可重用程度。

如果这是您的应用程序的“一个”要求,那么Map 和客户端属性是合理的解决方案。

Map 对其他开发人员来说更加明显,很明显您正在尝试做什么。然而,它很容易搞砸。地图要么包含不相关的数据,要么由于某些人忘记/或不知道遵守要求而丢失数据。

clientProperty 在这个意义上确实解决了Map 的一些缺点,因为您正在处理单个组件,而不是组件和Map(尽管开发人员仍然可能忘记设置属性),但与Map 相比,可见性要低得多。开发人员可能需要更长的时间才能了解您如何存储/检索数据。

不过,它确实具有简单的优点。您可以传递对标签的引用,您不仅拥有标签,还拥有Person

自定义标签为您提供了灵活性的机会。这比clientProperty 解决方案更明显,因为它定义了公共方法。它还使您有机会在创建标签时设置TransferHandler,而不必在每次要重复使用解决方案时单独建立每个。

归根结底就是这个。您想要一个快速的、一次性的解决方案,还是想要一个独立且可重复使用的解决方案。 MapclientProperty 选项的实施和使用相对较快。自定义组件将花费更多精力,但通常会产生更可重用的解决方案。这完全取决于你;)

【讨论】:

  • 所有很好的答案,谢谢。我认为最后一个可能最适合我的需求,因为我将使用 DnD 设置自定义对象。
猜你喜欢
  • 2017-08-30
  • 2011-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-28
  • 2011-01-19
相关资源
最近更新 更多