我正在摸着这个。以下是正在运行的示例。我在流布局中有两个Swing Lists,每个都有一个简单的数据模型。根据我实例化FlowLayout的方式,第二个列表不显示其元素。怪异。
import javax.swing.*;
import java.awt.*;
public class ListboxTest2 {
public 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);
}
}
答案 0 :(得分:2)
在第一次尝试中,第二个列表仅显示一个元素。 在所有后续尝试中,它都正确显示。 奇怪。
我会尝试在初始化的其余部分之后移动setVisible(true)。
答案 1 :(得分:2)
将列表框包装在JScrollPane中总是一个好习惯,因为它允许您在项目超出可见区域时滚动。将列表框添加到面板中。
panel.add(new JScrollPane(list1));
panel.add(new JScrollPane(list2));
答案 2 :(得分:2)
这与布局管理器无关。您需要在pack()
上调用JFrame
才能使其显示,否则行为有点随机,因为您的主线程和EDT之间存在竞争条件。
理论上,UI的所有操作都必须在EDT中进行,包括原始设置。实际上,您可以通过在EDT启动之前完全进行设置来避免这种情况(我相信通常会在第一个组件可见时发生)。我怀疑在你的代码中,grabFocus()
导致在主线程上计算UI的布局,然后导致EDT由setVisible()
开始的竞争条件。