5

My ultimate goal is to have a JList which refreshes its content at runtime, and I have found a solution that works from this post here on SO, however I am curious why my original idea did not.

As of now, I have something like this setup and it works:

DefaultListModel default = new DefaultListModel();

for(int i = 0; i < array.size() ; ++i){
   test.addElement(array.get(i));
}
list.setModel(default);

Below was my original plan. I wanted to have a class which implemented ListModel be passed as an argument, hoping it would refresh the JList.

SomeClass test = new SomeClass(); //Implements ListModel
list.setModel(test);

or

SomeClass test = new SomeClass(); //Implements ListModel
list = new JList(test);

Neither of these work, which confuses me. Could these last two methods work some how, the code is so much cleaner.

Thanks.

Community
  • 1
  • 1
Koop
  • 401
  • 2
  • 5
  • 10
  • Passing a class ListModel instead of an instance of this class is a compilator error. Why are you confusing ? – Istao Nov 20 '10 at 09:10
  • I think my code demo is a bit misleading sorry. Thats what I was doing, I will change the code to make this more clear. – Koop Nov 20 '10 at 09:16
  • 1
    Why don't those last two methods work? Please provide the error you're seeing. If `SomeClass` extends `ListModel`, then both of those methods will work. – Nate W. Nov 20 '10 at 10:01
  • 1
    your SomeClass code would be good to see. – akf Nov 20 '10 at 17:26

4 Answers4

3

The first approach should work if you implement the ListModel correctly. The key is that when you change the data you need to invoke:

fireContentsChanged(...);

from the AbstractListModel (which I assume you extend). Invoking this method will tell the JList to repaint itself.

The second approach won't work because you just create a new JList component that is sitting in memory. Creating the component does not add it to the GUI. So if you use this approach you need to remove the original JList from the GUI and then add your new JList to the GUI. This is not very convenient and is a good reason why this approach should not be used. Setting the model is always the preferred approach.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • is fireContentsChanged() supposed to be part of AbstractListModel or a custom method? Also, does this simply reiterate through all the values? Thanks. – Koop Nov 20 '10 at 19:22
  • When you add a ListModel to a JList, the JList adds a listener to the model. When you change the model, the model notifies the view (the list) that data has changed so the view can repaint itself. This notification is done by the fireXXX methods which are part of the AbstractListModel. That is why when you create a custom model you should extend the abstract model to you don't have to reinvent the wheel and notify the view. All you do is invoke the approriate fireXXX method. – camickr Nov 21 '10 at 00:01
1

The first case seems like a solution in my mind. Can you provide a testable example?

The second case will not work because you are just reusing a variable and are not actually changing the JList on the Gui. I am assuming you already added this list to the guy earlier in code.

jzd
  • 23,473
  • 9
  • 54
  • 76
0

Most likely your implementation of ListModel is wrong.

milan
  • 2,355
  • 2
  • 23
  • 38
0

Why not using:

DefaultListModel<String> lstList = new DefaultListModel<String>();
Zoe
  • 27,060
  • 21
  • 118
  • 148