tags:

views:

1943

answers:

4

Hi!

I'm trying to change a JList inside a JScrollPane dynamically, using

myList.setListData(someArray);

After this I would expect the JScrollPane to show Scrollbars as needed, but this doesn't happen. Googling the issue was not very helpful. I tried various combinations of the following methods, with little success (basically poking through the api docs):

myScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
myList.validate(); myScrollPane.validate();
myScrollPane.setPreferredSize(Dimension someDimension);
myScrollPane.setViewportView(moduleList);
myScrollPane.setLayout(...);

When using the first method a scrollbar appears, but it doesn't get activated by the model change. I also hooked into the PropertyChangeEvent and validated that the JList fires and event when the model changed. What am I missing here? What method do I have to use to make this work, or even better what property would make this work out of the box?

+3  A: 

just wrote a little sample app to test this behaviour, and it works out of the box. when you modify the list data, vertical and horizontal scrollbars are added to the scrollpane as needed by default.

public class Frametest {

private JList list;

public Frametest() {
 JFrame f = new JFrame("Scrollable JList");
 f.setSize(200, 300);
 JScrollPane jsp = new JScrollPane();  
 list = new JList();
 jsp.getViewport().add(list);
 f.getContentPane().setLayout(new BorderLayout());
 f.getContentPane().add(jsp, BorderLayout.CENTER);
 JButton button = new JButton("update");
 button.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent arg0) {
   Object[] objects = new Object[20];
   for(int i=0; i<20; i++) {
    objects[i] = "foo foo foo foo foo foo foo foo foo foo foo foo "+i;
   }
   list.setListData(objects);
  }
 });
 f.getContentPane().add(button, BorderLayout.SOUTH);
 f.setVisible(true);  
}

public static void main(String[] args) {
 new Frametest();
}}
räph
I suspect he might be adding the data AFTER the list has been made visible since he is talking about model change...
willcodejavaforfood
Yes, that's working in the example! When you hit the update button (list has already been made visible), the model is changed and the scrollbars are adjusted.
räph
Yes, I'm pretty much doing exactly what you did, but your code works for me - I'll have a closer look of what I'm NOT doing ... I suspect it could be something with the layout - thanks!
VolkA
+2  A: 

Have you tried calling the validate or revalidate method of the JList upon making changes to the list data?

myList.setListData(someArray);
myList.revalidate();

Just for your information, I just did a quick investigation of the difference between validate and revalidate and it seems to be that validate will the layout for the component the method was called on and its children, while revalidate will go all the way up to its highest parent and then perform layout changes and such to all its children.

Calling revalidate on myList will not only validate the list itself, but it will also validate the scroll pane as well, therefore, affecting the visibility of the scroll bar depending on the items being drawn in the list.

coobird
Yeah, I tried both, but with no effect ...
VolkA
+1  A: 

This looks wrong:

jsp.getViewport().add(list);

Instead use:

jsp.setViewportView(list);

or

new JScrollPane(list);

and the list will be added correctly to the scrollpane. Adding it this way tells the scrollpane to listen to it for changes.

Keilly
+3  A: 

if the preferredSize is set on JList, even if (0, 0), then JScrollPane doesn't work - ensure that it is unset, setPreferredSize(null) if necessary

see mrtextminer as follows

The solution to this problem is to not setting the preferredSize of the JList (removing the setting statement). In Netbeans IDE 5.5.1, unsetting the preferredSize of the JList can be achieved by right clicking on the preferredSize property of the JList and then selecting “restoring default value”.

In conclusion, set preferredSize of the JScrollPane only. Do not set the preferredSize of the JList.

evanx
That actually fixed a long-standing bug in one of my applications. Thank you. :)
Bombe