0

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?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Sergei Podlipaev
  • 1,331
  • 1
  • 14
  • 34
  • 1
    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. General tips: 1) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). 2) One way to get image(s) for an example is to hot link to images seen in [this Q&A](http://stackoverflow.com/q/19209650/418556). .. – Andrew Thompson Nov 08 '16 at 18:59
  • .. 3) Application resources will become embedded resources by the time of deployment, so it is wise to start accessing them as if they were, right now. An [tag:embedded-resource] must be accessed by URL rather than file. See the [info. page for embedded resource](http://stackoverflow.com/tags/embedded-resource/info) for how to form the URL. – Andrew Thompson Nov 08 '16 at 18:59
  • To expand on my first comment. 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, – Andrew Thompson Nov 08 '16 at 19:03

2 Answers2

1

Thanks, Andrew Thompson! Seems like using bigger size of grid works well! enter image description here

Sergei Podlipaev
  • 1,331
  • 1
  • 14
  • 34
1

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);
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433