Search code examples
javaswinggrid-layout

Java Swing GridLayout


I am making a GUI application, and I made a JPanel with JScrollPane. The problem is that when adding elements to it, first few elements taking all available space, which looks ugly. How can I prevent them from that?

Here is the code:

import javax.swing.*;
import java.awt.*;

public class VersionPanel extends JPanel {
    private final JPanel panel;

    public VersionPanel() {
        this.setLayout(new BorderLayout());
        this.panel = new JPanel(new GridLayout(0, 1));
        JScrollPane scrollPane = new JScrollPane(this.panel);
        scrollPane.setPreferredSize(new Dimension(400, 300));
        this.add(scrollPane, BorderLayout.CENTER);
    }

    public void addVersionLabel(VersionLabel label) {
        this.panel.add(label);
        this.panel.revalidate();
        int height = (int) this.panel.getPreferredSize().getHeight();
        this.panel.scrollRectToVisible(new Rectangle(0, height, 10, 10));
    }
}

Here is the code of VersionLabel:

import javax.swing.*;
import javax.swing.border.BevelBorder;
import java.awt.*;
import java.awt.event.ActionListener;

public class VersionLabel extends JPanel {
    private final ActionListener launch;
    private final ActionListener delete;
    private final ActionListener install;

    public VersionLabel(String versionNumber, boolean installed, ActionListener launch, ActionListener delete, ActionListener install) {
        this.launch = launch;
        this.delete = delete;
        this.install = install;

        this.setLayout(new GridLayout(1, 2));
        this.add(this.getLeftPanel(versionNumber, installed));
        this.add(this.getRightPanel(installed));
        this.setBorder(new BevelBorder(BevelBorder.RAISED, Color.RED, Color.RED)); //test border
        this.setMaximumSize(this.getMinimumSize());
    }

    private JPanel getLeftPanel(String versionNumber, boolean installed) {
        return new JPanel() {{
            this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
            this.add(new JLabel(versionNumber));
            this.add(new JLabel(installed ? "Installed" : "Not Installed"));
        }};
    }

    private JPanel getRightPanel(boolean installed) {
        return new JPanel(new FlowLayout(FlowLayout.RIGHT)) {{
            if(installed) {
                this.add(new JButton("Launch") {{ this.addActionListener(launch); }});
                this.add(new JButton("Delete") {{ this.addActionListener(delete); }});
            } else {
                this.add(new JButton("Install") {{ this.addActionListener(install); }});
            }
        }};
    }
}

Solution

  • Thanks to @DontKnowMuchButGettingBetter! I added a new JPanel to my code:

    public VersionPanel() {
            this.setLayout(new BorderLayout());
            this.panel = new JPanel(new GridLayout(0, 1));
            JPanel bPanel = new JPanel(new BorderLayout());
            bPanel.add(this.panel, BorderLayout.PAGE_START);
            JScrollPane scrollPane = new JScrollPane(bPanel);
            scrollPane.setPreferredSize(new Dimension(400, 300));
            this.add(scrollPane, BorderLayout.CENTER);
    }