Java Swing-GridLayout组件未填满所有可用空间

Java Swing-GridLayout组件未填满所有可用空间,java,swing,jscrollpane,layout-manager,grid-layout,Java,Swing,Jscrollpane,Layout Manager,Grid Layout,我已经搜索了StackOverflow,但所有的问题似乎都与我的问题完全相反 我正在编写代码,用GridLayout动态地将JLabels添加到JPanel,所有这些都包含在JScrollPane中。这是一个SSCCE: private JFrame frame; private JPanel panel; static Test window; private JScrollPane scrollPane; public static void main(final String[] arg

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

我正在编写代码,用
GridLayout
动态地将
JLabels
添加到
JPanel
,所有这些都包含在
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);
}
私有JFrame;
私人JPanel小组;
静态测试窗口;
私有JScrollPane滚动窗格;
公共静态void main(最终字符串[]args){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
窗口=新测试();
window.frame.setVisible(true);
}捕获(最终异常e){
e、 printStackTrace();
}
}
});
对于(int i=0;i<100;i++){
试一试{
EventQueue.invokeAndWait(新的可运行(){
@凌驾
公开募捐{
最终JLabel标签=新JLabel(“测试”);
标签。设置尺寸(160,40);
标签.设置水平对齐(旋转角度.中心);
//最终确定图形用户界面
窗口.面板.添加(标签);
window.panel.revalidate();
window.panel.repaint();
试一试{
睡眠(100);
}捕获(最终异常e){
e、 printStackTrace();
}
}
});
}捕获(最终异常e){
e、 printStackTrace();
}
}
}
公开考试(){
初始化();
}
私有void初始化(){
frame=新的JFrame();
机架立根(100100500200);
frame.getContentPane().setLayout(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel=新的JPanel();
panel.setLayout(新的GridLayout(0,3));
final JPanel outerPanel=新JPanel();
setLayout(新的FlowLayout());
外面板添加(面板);
scrollPane=新的JScrollPane(outerPanel、ScrollPaneConstants.VERTICAL\u SCROLLBAR\u根据需要,ScrollPaneConstants.HORIZONTAL\u SCROLLBAR\u NEVER);
滚动窗格.立根(12,0,460,160);
frame.getContentPane().add(滚动窗格);
}
据我所知,在
GridLayouts
中,“每个组件占用其单元格内的所有可用空间。”然而在这里,
jlabel
实际上并不占用
JPanel
中的所有可用空间

我不确定我的错误在哪里。是在
GridLayout
中还是在周围
组件中
没有给
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); // !!
在Swing GUI中,
Thread.sleep(…)
也是危险的代码。如果您希望延迟添加组件,请使用该作业的最佳Swing工具:a。比如说

    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();
final int timerDelay=100;
最终整数maxLabelCount=100;
新计时器(timerDelay,新ActionListener(){
私有int-labelCount=0;
@凌驾
已执行的公共无效操作(操作事件evt){
if(labelCount
您想在这里做什么?尤其是这个
线程。sleep(100)在Swing事件线程上调用??请参见编辑以回答
线程。睡眠(100)
就在那里,这样我可以看到一个接一个地添加JLabel,同时保持代码简短。同样,这是危险的代码。如果您希望看到它们被添加,请使用如下所示的Swing计时器。