thegaffney thegaffney - 3 months ago 7
Java Question

Can not figure out a simple 4 box JPanel layout

I have been trying for hours to get

JPanel
in Java to contain these 4 other panels in this configuration (see picture)


  • The blue box should never change size.

  • The white box should never change height, can get wider though.

  • The dark grey box should never change widths, can get taller though.

  • The light grey box can get taller or wider.



Seems pretty simple to me, I did it in C# the other day and it was a breeze. Set the position, the width, height, and whether a certain side was anchored or not, boom done, I was starting to like java more than C until I ran into this.

I've tried countless combinations of
GridBagLayout
, multiple nested
BoxLayout
instances. They all seem to do very strange things, like make each panel a tiny 4 x 4 square, or there is crazy padding around them, or the ones that need to re-size with the window, don't.

Is there some kind of magic combination that can achieve this? Does the
null
layout do anchoring or percent dimensions.

The closest I've gotten is the bottom image with
GridBagLayout
, which looks good when it loads, but does that when you re-size the window.

enter image description here

enter image description here

Here is the code that got the above images

class MainPanel extends JPanel {
public MainPanel(){
this.setBackground(new Color(216,216,216));
this.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();

JPanel topTitle = new JPanel();
topTitle.setPreferredSize(new Dimension(140, 40));
topTitle.setMinimumSize(new Dimension(140, 40));
topTitle.setBackground(new Color(174, 216, 249));
c.weightx = 0.5;
c.gridx = 0;
c.gridy = 0;
this.add(topTitle,c);

JPanel mainHeader = new JPanel();
mainHeader.setPreferredSize(new Dimension(1060, 40));
mainHeader.setMinimumSize(new Dimension(1060, 40));
mainHeader.setBackground(Color.WHITE);
c.gridx = 1;
c.gridy = 0;
this.add(mainHeader,c);

JPanel sideNav = new JPanel();
sideNav.setPreferredSize(new Dimension(140, 760));
sideNav.setMinimumSize(new Dimension(140, 760));
sideNav.setBackground(new Color(110,110,110));
c.gridx = 0;
c.gridy = 1;
this.add(sideNav,c);

JPanel dataPanel = new JPanel();
dataPanel.setPreferredSize(new Dimension(1060, 760));
dataPanel.setMinimumSize(new Dimension(1060, 760));
dataPanel.setBackground(new Color(216,216,216));
c.gridx = 1;
c.gridy = 1;
this.add(dataPanel,c);
}


}

Answer

GUI at minimum size

GUI at minimum size

GUI stretched wider & taller

GUI stretched wider & taller

It's all about getting appropriate resize weights & fill values..

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

public class FourPanelLayout {

    private JComponent ui = null;

    FourPanelLayout() {
        initUI();
    }

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

        ui = new JPanel(new GridBagLayout());
        // It appears you don't want space around the panels.
        // If not, commment out or remove this line.
        ui.setBorder(new EmptyBorder(4,4,4,4));

        // create the panels, each with a transparent image to suggest a size
        JPanel bluePanel = new JPanel();
        bluePanel.setBackground(Color.CYAN);
        bluePanel.add(new JLabel(new ImageIcon(getTransparentImage(40, 20))));

        JPanel darkGrayPanel = new JPanel();
        darkGrayPanel.setBackground(Color.DARK_GRAY);
        darkGrayPanel.add(new JLabel(new ImageIcon(getTransparentImage(40, 20))));

        JPanel whitePanel = new JPanel();
        whitePanel.setBackground(Color.WHITE);
        whitePanel.add(new JLabel(new ImageIcon(getTransparentImage(40, 20))));

        JPanel grayPanel = new JPanel();
        grayPanel.setBackground(Color.GRAY);
        grayPanel.add(new JLabel(new ImageIcon(getTransparentImage(360, 80))));

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.BOTH;
        gbc.weightx = 0.0f;
        gbc.weighty = 0.0f;
        gbc.gridx = 0;
        gbc.gridy = 0;

        ui.add(bluePanel, gbc);

        gbc.weightx = .5f;
        gbc.gridx = 1;
        ui.add(whitePanel, gbc);

        gbc.weighty = .5f;
        gbc.gridy = 1;
        ui.add(grayPanel, gbc);

        gbc.weightx = 0f;
        gbc.gridx = 0;
        //gbc.gridy
        ui.add(darkGrayPanel, gbc);
    }

    /* We use transparent images to give panels a natural size. */
    private Image getTransparentImage(int w, int h) {
        return new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
    }

    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) {
                }
                FourPanelLayout o = new FourPanelLayout();

                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