2

I'm doing a drag and drop of custom objects into JLabels and am able to reference the object during the transfer process (change label String to received object toString), but unsure of how to actually store the custom object in the JLabel or build a reference.

What is the best way to accomplish this during the transfer process?

Here is the working transfer code that receives the object and uses it to set text (much thanks to a previous answer: 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;
        }

The JLabels have specific instance variables that I'd like to store them to. Since I have the component (JLabel) and value (custom object), can I make this link?

Worst case scenario, I just have to build a TransferHandler for each label and reference the value exactly. Is this maybe best practice anyways?

Community
  • 1
  • 1
Andy Levesque
  • 560
  • 5
  • 21
  • 2
    Why would you store an object in a JLabel? You could use a `Map` such as with a HashMap if you wish to associate a Person with a JLabel, but I guess you'd probably rather put the Person into an ArrayList or other collection. – Hovercraft Full Of Eels Dec 13 '12 at 17:48
  • I'm not familiar with mapping, so that might be the trick. – Andy Levesque Dec 13 '12 at 17:49
  • As a (very sloppy) workaround in the meantime, I'm using the JLabel tooltip as the reference with an if statement matching the tooltip with the associated value... I definitely need to study up on mapping. – Andy Levesque Dec 13 '12 at 17:51
  • 1
    What information are you storing, and why must it be associated with the JLabel? You would only use the Map if you must associated the object with the JLabel, but again that may not even be necessary. A JLabel is used for display of information not for storage. You need to clarify the problem you're trying to solve, not how you're trying to solve it. – Hovercraft Full Of Eels Dec 13 '12 at 17:54
  • 2
    You can use the `JComponent` methods `putClientProperty()` and `gettClientProperty()` as needed. Also cite this [answer](http://stackoverflow.com/a/13856193/230513) to your previous question on this topic. – trashgod Dec 13 '12 at 18:12
  • @HovercraftFullOfEels it is to reference an object with the JLabel. – Andy Levesque Dec 13 '12 at 18:47
  • @trashgod would this support objects? – Andy Levesque Dec 13 '12 at 18:48

1 Answers1

5

You have a number of choices that I can see

Choice #1

Create a Map of some kind and store the object against the label, using the label as it's key

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

Then in your import method

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

Choice #2

Take advantage of the put/getClientProperty to store the value against a named key...

In your import method...

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

And when you need it again

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

Choice #3

Create a custom label that is capable of referencing the person directly.

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;
    }
}

Basically, you would use this component in place of the normal JLabel, make sure you cast it correctly.

Credit to Hovercraft and trashgod for mentioning most of this first.

Final Choice

The final choice will come down to your own design, requirements and how re-usable you want the solution to be.

If this is a "one" off requirement for your application, then the Map and client properties are reasonable solutions.

The Map is more highly visible to other developers, it obvious what you are trying to do. It is, however, easy to mess up. Having the map either contain irrelevant data or have missing data because some one forgot to/or didn't know to follow the requirements.

The clientProperty does solve some the short comings of the Map in this sense, as you a re dealing with a single component, not a component and a Map (although it's still possible for developers to forget to set the property) but has a much lower visibility when compared to the Map. It might take longer for developers to realise how you are storing/retrieving the data.

It does, how ever, have the advantage of been simple. You can pass a reference to the label and you have not just the label, but also the Person as well.

The custom label provides you the opportunity for flexibility. It's more obvious then the clientProperty solution, as it has defined public methods. It also allows you the opportunity to setup the TransferHandler when the label is created, rather then having to establish each one individually each time you want to re-use the solution.

What it's going to come down to is this. Do you want a quick, once of solution, or do you want something to is self-contained and re-usable. The Map and clientProperty choices are relatively quick to implement and use. The custom component will take a little more effort but will generally result in a more re-usable solution. It's all up to you ;)

Freek de Bruijn
  • 3,552
  • 2
  • 22
  • 28
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • All very good answers, thank you. I think the last one will probably suit my needs the best since I'll be setting the custom object with a DnD. – Andy Levesque Dec 13 '12 at 20:50