Is there a way to make GridLayout leave empty cells?

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

The second JPanel has a significantly smaller number of filled cells, and this causes each button to stretch to fill the entire row. enter image description here

Is there a way to force GridLayout to respect empty cells, so the buttons in both JPanels are the same size?

+7
java layout-manager swing grid-layout jpanel
source share
2 answers

Use nested layouts to get your desired result. Some layouts respect the preferred size of the components, and some do not. GridLayout is one of those that do not. See this answer to see what to do and which not.

For example, you can insert 13 buttons in a GridLayout nested in another JPanel using 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(); } }); } } 
+7
source share

Is there a way to force GridLayout to respect empty cells, so the buttons in both JPanels are the same size?

This can certainly be done with GridLayout , just “fill” the empty squares with JLabel , which has no text.

eg. Here are two grid layouts, both complemented by three lines.

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); } } 
+6
source share

All Articles