我已经搜索了StackOverflow,但是所有问题似乎都与我的问题完全相反。

我正在编写将JLabels动态添加到带有JPanelGridLayout的代码,所有这些都包含在JScrollPane中。这是一个SSCCE:

private JFrame frame;
private JPanel panel;
static Test window;
private JScrollPane scrollPane;

public static void main(final String[] args) {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            try {
                window = new Test();
                window.frame.setVisible(true);
            } catch (final Exception e) {
                e.printStackTrace();
            }
        }
    });

    for (int i = 0; i < 100; i++) {
        try {
            EventQueue.invokeAndWait (new Runnable() {
                @Override
                public void run() {
                    final JLabel label = new JLabel("Test");
                    label.setSize(160, 40);
                    label.setHorizontalAlignment(SwingConstants.CENTER);
                    // Finalise GUI
                    window.panel.add(label);
                    window.panel.revalidate();
                    window.panel.repaint();
                    try {
                        Thread.sleep(100);
                    } catch (final Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        } catch (final Exception e) {
            e.printStackTrace();
        }
    }
}

public Test() {
    initialize();
}

private void initialize() {
    frame = new JFrame();
    frame.setBounds(100, 100, 500, 200);
    frame.getContentPane().setLayout(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    panel = new JPanel();
    panel.setLayout(new GridLayout(0, 3));

    final JPanel outerPanel = new JPanel();
    outerPanel.setLayout(new FlowLayout());
    outerPanel.add(panel);

    scrollPane = new JScrollPane(outerPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    scrollPane.setBounds(12, 0, 460, 160);
    frame.getContentPane().add(scrollPane);
}


据我了解,在GridLayouts中,“每个组件占用其单元格中的所有可用空间。”但是在这里,JLabels实际上并不会占用JPanel中的所有可用空间。

我不确定我的错误在哪里。是在GridLayout还是周围的Components中没有给GridLayout足够的空间?

谢谢大家

最佳答案

您的JLabel将占用所有可用空间。是您的JPanel很小。用边框自己测试一下:

    panel = new JPanel();
    panel.setLayout(new GridLayout(0, 3));

    // **** add this to see ****
    panel.setBorder(BorderFactory.createLineBorder(Color.BLUE));


如果要使标签填充顶部,请对外部面板使用不同的布局。注意标记为// !!注释的更改:

    final JPanel outerPanel = new JPanel();
    // !! outerPanel.setLayout(new FlowLayout());
    outerPanel.setLayout(new BorderLayout()); // !!
    // !! outerPanel.add(panel);
    outerPanel.add(panel, BorderLayout.PAGE_START); // !!


另外,Thread.sleep(...)是Swing GUI中的危险代码。如果要延迟添加组件,请使用最佳的Swing工具进行作业:Swing Timer。例如

    final int timerDelay = 100;
    final int maxLabelCount = 100;
    new Timer(timerDelay, new ActionListener() {
        private int labelCount = 0;
        @Override
        public void actionPerformed(ActionEvent evt) {
            if (labelCount < maxLabelCount) {
                final JLabel label = new JLabel("Test");
                // !! label.setSize(160, 40); // NO!
                label.setHorizontalAlignment(SwingConstants.CENTER);
                // Finalise GUI
                window.panel.add(label);
                window.panel.revalidate();
                window.panel.repaint();
            } else {
                // stop this timer
                ((Timer) evt.getSource()).stop();
            }
            labelCount++;
        }
    }).start();

09-10 09:00
查看更多