This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
I have a GUI that contains a list in one panel. I am trying to serialize that list to a file, and then later deserialize it. When I replace the list object with the deserialize list, the list in the GUI goes blank. However, if I write this new list to a file I see that it actually contains the data that it should. It's just not appearing in the GUI. Does anyone have any suggestions?
Joined: Nov 07, 2007
I realized that the problem had to do with reassigning my listModel. I had orginally done something like this:
Later in my code, I serialized listModel. Then I tried to deserialize listModel in another method. I tried to just do
However, when I stopped there, I think that list and listPane still pointed to the old listModel memory space? I added the following code:
And now the deserialized list appears in the GUI.
In the course of this I started to question whether I should be serializing listModel as a big chunk or whether I should serialize the members, and then deserialize and add them one at a time (vs. replacing the whole list model). This is my first time using serialization, so I'm just trying stuff out.
Anyway, I hope this is helpful to someone else. I think the principles here apply any time you are trying to change a GUI object that is contained by other objects.
The JList is just the view and the ListModel holds the data. JList has a very convenient method: setListData. Whenever you construct a JList without specifying any custom model, it just picks up the default model.
Instead of removing/adding the JList(view) you can persist/retrieve the data and call the setListData() on the JList and your functionality would still be achieved.
Using JList.setListData sounded like a great idea, so I tried it. However, it seems to only take an array of Objects, and since I serialized the listModel as a chunk this doesn't seem to work. I think if I saved each element individually it probably would.
... it seems to only take an array of Objects, and since I serialized the listModel as a chunk this doesn't seem to work.
You dont serialize the listModel but the List itself! Remember, the model is just a convenient way for the JList to pick up the data..but the data is really inside the List (By List I mean java.util.List).
So you switch to de/serlializing the java.util.List. How do you pass the java.util.List to the listModel?
The java.util.List has list.toArray() which gives you an Object array. Arrays.asList(Object myArray) will give you a java.util.List. [ April 08, 2008: Message edited by: Maneesh Godbole ]
I looked up ListModel on the java.sun.com page and got the following description:
public interface ListModel This interface defines the methods components like JList use to get the value of each cell in a list and the length of the list. Logically the model is a vector, indices vary from 0 to ListDataModel.getSize() - 1. Any change to the contents or length of the data model must be reported to all of the ListDataListeners.
public class DefaultListModel extends AbstractListModel This class loosely implements the java.util.Vector API, in that it implements the 1.1.x version of java.util.Vector, has no collection class support, and notifies the ListDataListeners when changes occur. Presently it delegates to a Vector, in a future release it will be a real Collection implementation.
So, since DefaultListModel is Vector-like, it makes sense to me to save it instead of the JList GUI component. Thoughts?
Thanks for discussing this-- I really want to understand it better. [ April 08, 2008: Message edited by: Jess Dancel ]
You are correct in thinking of the ListModel as the data holder since it internally uses vector like structure to hold data. However, in addition, it also has the addition functionality (among others) to maintain a list of DataLsiteners and inform them as required. In effect, these listeners are nothing but the views (like JList). So whenever the data inside the model changes, the listeners get notified, so that they can repaint themselves to reflect the latest data state.
Now, in your case, you really dont care about the model and listeners and notifications. All you want is to load the persisted data from the disk and display it in the UI. As I had mentioned earlier, if you dont specify any ListModel the JList will pick up the DefaultListModel. So, even if you deal with the list in terms of pure data, you still get the functionality of the view automatically getting refereshed whenever the data changes.
So does it now make sense, to persist the pure data, i.e. java.util.List or Object array or whatever you want instead of the whole list model?