为什么这个Swing List没有显示其元素?

时间:2010-02-23 10:22:00

标签: java swing layout awt

我正在摸着这个。以下是正在运行的示例。我在流布局中有两个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);
    }

}

3 个答案:

答案 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()开始的竞争条件。