Sergei Podlipaev Sergei Podlipaev - 27 days ago 10
Java Question

How to set icons without gap?

I'm using java swing. I want to add grid of pictures.

public class LayoutTest {
JFrame frame = new JFrame("GridLayout demo");
JPanel panel = new JPanel();
JButton btn1 = new JButton("First");
JButton btn2 = new JButton("Second");
JButton btn3 = new JButton("Third");
JButton btn4 = new JButton("Fourth");
JPanel panel2 = new JPanel();
JButton btn12 = new JButton("First2");
JButton btn22 = new JButton("Second2");
JButton btn32 = new JButton("Third2");
JButton btn42 = new JButton("Fourth2");
JPanel panel3 = new JPanel();
JButton btn13 = new JButton("First2");
JButton btn23 = new JButton("Second2");
JButton btn33 = new JButton("Third2");
JButton btn43 = new JButton("Fourth2");

JLabel label13 = new JLabel(new ImageIcon("pictures/building.jpg"), JLabel.CENTER);
JLabel label23 = new JLabel(new ImageIcon("pictures/building2.png"), JLabel.CENTER);
JLabel label33 = new JLabel(new ImageIcon("pictures/building.jpg"), JLabel.CENTER);
JLabel label43 = new JLabel(new ImageIcon("pictures/building2.png"), JLabel.CENTER);
public LayoutTest() {
panel3.setLayout(new GridLayout(2,2,0,0));
panel3.add(label13);
panel3.add(label23);
panel3.add(label33);
panel3.add(label43);

frame.add(panel3);

frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
// frame.setSize(40,40);
frame.setVisible(true);
}

}


As a result I get this: this image. I'm using gridLayout. My pictures are 20x20 pixels size. How can I add images without this horizontal gap?

Answer

It appears that the frame decorations are forcing the extra size. If the four icons were added in a single row, the gap should decrease or disappear.

The default layout for a frame is BorderLayout. When a component is added to a border layout without constraint being specified, it will end up in the CENTER. The component (panel3) added to the center of a border layout will be stretched to fill the entire width and height available. A GridLayout will assign an equal width and height as needed for the widest and tallest grid cell. So the behaviour could also be avoided by adding panel3 to either the LINE_START or LINE_END of the content pane - these positions will stretch height but respect width.

Here is an example which demonstrates the effect within each constraint of a border layout.

enter image description here enter image description here

import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class GridLayoutSpace {

    private JComponent ui = null;

    GridLayoutSpace() {
        initUI();
    }

    public void initUI() {
        if (ui!=null) return;

        ui = new JPanel(new BorderLayout());
        ui.setBorder(new EmptyBorder(4,4,4,4));

        addFourIcons(Color.ORANGE, BorderLayout.PAGE_START);
        addFourIcons(Color.ORANGE, BorderLayout.PAGE_END);

        addFourIcons(Color.BLUE, BorderLayout.LINE_START);
        addFourIcons(Color.BLUE, BorderLayout.LINE_END);

        addFourIcons(Color.YELLOW, BorderLayout.CENTER);
    }

    private void addFourIcons(Color bg, String constraint) {
        JPanel p = new JPanel(new GridLayout(0, 2, 0, 0));
        p.setBackground(bg);
        ui.add(p, constraint);
        p.add(new JLabel(new ImageIcon(getImage(Color.RED))));
        p.add(new JLabel(new ImageIcon(getImage(Color.GREEN))));
        p.add(new JLabel(new ImageIcon(getImage(Color.GREEN))));
        p.add(new JLabel(new ImageIcon(getImage(Color.RED))));
    }
    int sz = 24;
    private BufferedImage getImage(Color color) {
        BufferedImage bi = new BufferedImage(sz, sz, BufferedImage.TYPE_INT_RGB);
        Graphics g = bi.getGraphics();
        g.setColor(color);
        g.fillRect(0,0, sz, sz);
        g.dispose();
        return bi;
    }

    public JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception useDefault) {
                }
                GridLayoutSpace o = new GridLayoutSpace();

                JFrame f = new JFrame(o.getClass().getSimpleName());
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                f.setLocationByPlatform(true);

                f.setContentPane(o.getUI());
                f.pack();
                f.setMinimumSize(f.getSize());

                f.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}
Comments