I'm scratching my head over this one. Below is a running sample. I have 2 Swing Lists in a flow layout each with a simple data model. Depending on how I instantiate the FlowLayout the 2nd List does not display its elements. Weird.
import javax.swing.*;
import java.awt.*;
public class ListboxTest2 {
pub开发者_Go百科lic static void main(String[] args) {
JFrame f = new JFrame();
f.setSize(500, 500);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
// this works
// panel.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 10));
// this doesn't
panel.setLayout(new FlowLayout());
final JList list1 = new JList();
list1.setPreferredSize(new Dimension(120, 60));
final JList list2 = new JList();
list2.setPreferredSize(new Dimension(120, 60));
final String[] strings1 = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", "Item 9", "Item 10", "Item 11", "Item 12"};
final String[] strings2 = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", "Item 9", "Item 10", "Item 11", "Item 12"};
list1.setModel(new AbstractListModel() {
public int getSize() {
return strings1.length;
}
public Object getElementAt(int index) {
return strings1[index];
}
});
panel.add(list1);
list2.setModel(new AbstractListModel() {
public int getSize() {
return strings2.length;
}
public Object getElementAt(int index) {
return strings2[index];
}
});
panel.add(list2);
f.add(panel);
f.setVisible(true);
list1.grabFocus();
list1.setSelectedIndex(0);
}
}
This has nothing to do with the layout manager. You need to call pack()
on the JFrame
before you make it visible, otherwise the behaviour is somewhat random because you have a race condition between your main thread and the EDT.
Theoretically, all manipulation of the UI must happen in the EDT, including the original setup. In practice, you can avoid this by doing the setup completely before the EDT starts (which I believe usually happens when the first component is made visible). I suspect that in your code, the grabFocus()
causes the layout of the UI to be computed on the main thread, which then results in a race condition with the EDT started by setVisible()
.
in the first attempt, the second list only displayed one element. in all subsequent attempts, it displayed it correctly. strange.
I would try to move setVisible(true) after the rest of the initialization.
It is always a good practice to wrap listboxes within a JScrollPane as it would allow you to scroll when items exceed the visible area. Add the list boxes to panel like this.
panel.add(new JScrollPane(list1));
panel.add(new JScrollPane(list2));
精彩评论