简体   繁体   中英

How do I retrieve the Object type that I placed into a DefaultListModel?

I hope I explained what I'm after here well enough. I'm having trouble retrieving an Object type that I've placed into a DefaultListModel.

public class HiddenIntegerFieldListItem {

    private final String displayedField;
    private final int    hiddenField;

    public HiddenIntegerFieldListItem( String dField, int hField ) {
        displayedField = dField;
        hiddenField    = hField;
    }

    public String getDisplayedField() { return displayedField; }
    public int getHiddenField() { return hiddenField; }

    @Override
    public String toString() { return displayedField; }

}

... elsewhere ...

DefaultListModel listModel = new DefaultListModel();
listModel.addElement( new HiddenIntegerFieldListItem( "The String", 4) );
jList.setModel( listModel );

And here's the problem, when I go to retrieve it, it tells me it can't convert this to a String. But I put in an Object ... so why isn't it returning me my Object? The compiler is fine with everything ... up until I go to get my Object out of the model. It gives me an incompatible type warning, looking for a String only when I do the following ...

HiddenIntegerFieldListItem hif = 
     (HiddenIntegerFieldListItem) jList.getModel().getElementAt( 0 );

What am I missing about this? Why does it only want to give me a String back and not my Object? It certainly accepted the Object, and the Object has a toString() method in it. And all I get is ...

incompatible types: String cannot be converted to HiddenIntegerFieldListItem

I'm stumped. Ready to give up on storing a primary key along with the item description in a list box and write a whole bunch of spaghetti code instead, which seems silly. :D Anybody see what I'm trying to do here and know what I'm doing wrong? Can't models store Objects anymore? Only Strings?

In general at compile time when you pull items out of a data structure it doesn't look at what the type it was when you put in (eg what it actually is), what it's looking for is the signature of that method.

And if the method signature of the get method on your data structure returns an Object, then as far as the compiler is concerned everything that you pull out of the data structure is an Object.

Now you know that the actual class is a HiddenIntegerFieldListItem - so what you need to do is to tell the compiler that that's what it is, by casting it to that type before using it.

(And if you cast it to the wrong type the compiler will let you - and then you'll get a dummy-spit at runtime.)

To make sure that you don't cast something to the wrong type you can use the instanceof operator.


The other thing to note is that by casting something you're not changing what it fundamentally is, you're changing its appearance to the rest of the code. So the interface or definition of Object has certain methods, but the interface or definition of HiddenIntegerFieldListItem has different methods, but all the Object methods are still available.

So here Object represents a certain minimal functionality, and then when you cast it you're saying it has more functionality than that, and you can legitimately cast it to anything in its super-class hierarchy. But you can't cast it to a subclass of its actual class, because that subclass might have data and methods which your object actually doesn't have.

Ok, mock up worked. The problem was the netbeans designer had typed the JList for me, for Strings, when I didn't know it was going to do that automagically. Once I removed that from the type parameters input in the designer tool, all was well. But here was the mock up, for anyone else wanting to store a key beside the visible string in a JList.

public class Test {

    class HiddenIntegerFieldListItem {

        private final String displayedField;
        private final int    hiddenField;

        public HiddenIntegerFieldListItem( String dField, int hField ) {
            displayedField = dField;
            hiddenField    = hField;
        }

        public String getDisplayedField() { return displayedField; }
        public int getHiddenField() { return hiddenField; }

        @Override
        public String toString() { return displayedField; }
    }

    public void tryIt() {

        javax.swing.JList<HiddenIntegerFieldListItem> jList = new javax.swing.JList<>();
        javax.swing.DefaultListModel listModel = new javax.swing.DefaultListModel();
        listModel.addElement( new HiddenIntegerFieldListItem( "The String", 4) );
        jList.setModel( listModel );

        // all good up till there, then ... oh wait, it worked now! ???

        HiddenIntegerFieldListItem hif = jList.getModel().getElementAt( 0 ); 
        System.out.println( hif.getHiddenField() + "" ); //Yay! It works! Output: 4
    }

    public static void main (String args[] ) {
        Test  t = new Test();
        t.tryIt(); 
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM