Java 有没有办法强制 GridLayout 留下空单元格?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21516056/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 09:06:08  来源:igfitidea点击:

Is there any way to force GridLayout to leave empty cells?

javaswingjpanellayout-managergrid-layout

提问by Pentarctagon

I have a JTabbedPane with 2 JPanels set to GridLayout(13, 11). The first JPanel has enough of the cells filled out that it leaves the empty cells. enter image description here

我有一个 JTabbedPane,其中 2 个 JPanel 设置为 GridLayout(13, 11)。第一个 JPanel 填充了足够多的单元格,留下空单元格。 在此处输入图片说明

The second JPanel has significantly fewer cells filled and this results in each button getting stretched to fill an entire row. enter image description here

第二个 JPanel 填充的单元格明显更少,这导致每个按钮被拉伸以填充整行。 在此处输入图片说明

Is there any way to get GridLayout to honor the empty cells, so the buttons in both JPanels are the same size?

有没有办法让 GridLayout 尊重空单元格,所以两个 JPanel 中的按钮大小相同?

采纳答案by Paul Samsotha

Use nested layouts to get your desired result. Some layouts respect the preferred size of components and some don't. GridLayoutis one of the ones that don't. Have a look at this answerto see which one's do and which one's don't.

使用嵌套布局来获得您想要的结果。有些布局尊重组件的首选大小,有些则不。GridLayout是不这样做的人之一。看看这个答案,看看哪些是做的,哪些是不做的。

For example, you could nest the 13 buttons in a GridLayoutnestedin another JPanelwith a FlowLayout

例如,您可以将 13 个按钮GridLayout嵌套在另一个嵌套中,JPanel并使用FlowLayout

JPanel p1 = new JPanel(new FlowLayout(FlowLayout.LEADING));
JPanel p2 = new JPanel(new GridLayout(13, 1));
for (int i = 0; i < 13; i++) {
    p2.add(new JButton("Button " + i));
}
p1.add(p2);

enter image description here

在此处输入图片说明

import java.awt.FlowLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Test6 {

    public Test6() {
        JPanel p1 = new JPanel(new FlowLayout(FlowLayout.LEADING));
        JPanel p2 = new JPanel(new GridLayout(13, 1));
        for (int i = 0; i < 13; i++) {
            p2.add(new JButton("Button " + i));
        }
        p1.add(p2);

        JFrame frame = new JFrame("Test Card");
        frame.add(p1);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                Test6 test = new Test6();
            }
        });
    }
}

回答by Andrew Thompson

Is there any way to get GridLayout to honor the empty cells, so the buttons in both JPanels are the same size?

有没有办法让 GridLayout 尊重空单元格,所以两个 JPanel 中的按钮大小相同?

It is certainly doable with GridLayout, simply 'fill' the blank squares with a JLabelthat has no text.

这当然是可行的GridLayout,只需用JLabel没有文本的'填充' 空白方块。

E.G. Here are two grid layouts, both padded to 3 rows.

EG 这是两个网格布局,都填充为 3 行。

Padded Grid Layout

填充网格布局

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.border.LineBorder;

class FillGridLayout {

    public static final JComponent getPaddedGrid(
            ArrayList<BufferedImage> images, int width, int height) {
        JPanel p = new JPanel(new GridLayout(height, width, 2, 2));
        p.setBorder(new LineBorder(Color.RED));
        int count = 0;
        for (BufferedImage bi : images) {
            p.add(new JButton(new ImageIcon(bi)));
            count++;
        }
        for (int ii=count; ii<width*height; ii++ ) {
            // add invisible component
            p.add(new JLabel());
        }
        return p;
    }

    public static void main(String[] args) {
        final ArrayList<BufferedImage> images = new ArrayList<BufferedImage>();
        int s = 16;
        for (int ii = s/4; ii < s; ii+=s/4) {
            images.add(new BufferedImage(ii, s, BufferedImage.TYPE_INT_RGB));
            images.add(new BufferedImage(s, ii, BufferedImage.TYPE_INT_RGB));
        }
        Runnable r = new Runnable() {
            @Override
            public void run() {
                JPanel gui = new JPanel(new BorderLayout(3,3));
                gui.add(getPaddedGrid(images, 3, 3), BorderLayout.LINE_START);
                gui.add(getPaddedGrid(images, 4, 3), BorderLayout.LINE_END);

                JOptionPane.showMessageDialog(null, gui);
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency
        SwingUtilities.invokeLater(r);
    }
}