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

…衆ロ難τιáo~ 提交于 2019-12-04 03:37:57
Paul Samsotha

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

For example, you could nest the 13 buttons in a GridLayout nested in another JPanel with a 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);

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();
            }
        });
    }
}

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

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

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

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);
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!