2

I would like to make a layout using Java Swing which looks like the following drawing.

layout sketch
(source: braun-abstatt.de)

On the left is a JPanel which is drawn through paintComponent() in a way that the graphics automatically scale when the window is resized. (The question isn't about that panel. That one's already done.)

Now I need some buttons (the black boxes, added in Photoshop for the drawing) to the right of the JPanel mentioned before. The height of the reddish areas at the top and bottom, next to which there should be just empty space, is calculated along the lines of CONSTANT_FACTOR * getHeight(). Next to each compartment on the left, there should be a group of buttons, lined up to the center of the respective compartment (see the blue lines).

The JPanel containing the buttons knows about the CONSTANT_FACTOR and the number of compartments, so it should be possible to feed this information into a layout manager.

Which layout manager would I best use to achieve this layout? I've read about all the different layout managers, but I can't quite figure out which one or which combination of them best fits in this case.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
tajmahal
  • 1,665
  • 3
  • 16
  • 29

3 Answers3

4

For example, by use of a different LayoutManager, a very easy and simple container, takes no more than 15-20 minutes:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

public class ThinLineFrame {
    private JFrame frame = new JFrame();
    private JScrollPane scrollPane;
    private JPanel panel = new JPanel();
    private JPanel panelNorth = new JPanel();
    private JPanel panelCenter = new JPanel();
    private JPanel panelCenterCh1 = new JPanel();
    private JPanel panelCenterCh2 = new JPanel();
    private JPanel panelCenterCh3 = new JPanel();
    private JPanel panelCenterCh4 = new JPanel();
    private JPanel panelCenterCh5 = new JPanel();
    private JPanel panelSouth = new JPanel();

    public ThinLineFrame() {
        panelNorth.setBackground(Color.red.darker());
        panelNorth.setPreferredSize(new Dimension(80, 30));
        //
        panelCenter.setBackground(Color.darkGray);
        panelCenter.setLayout(new GridLayout(5, 1, 2, 2));
        //
        panelCenterCh1.setLayout(new BorderLayout());
        JButton panelCenterCh1Button = new JButton();
        panelCenterCh1.add(panelCenterCh1Button, BorderLayout.CENTER);
        //
        JButton panelCenterCh2Button1 = new JButton();
        JButton panelCenterCh2Button2 = new JButton();
        panelCenterCh2.setLayout(new GridLayout(2, 1, 2, 2));
        panelCenterCh2.add(panelCenterCh2Button1);
        panelCenterCh2.add(panelCenterCh2Button2);
        //
        JButton panelCenterCh3Button1 = new JButton();
        JButton panelCenterCh3Button2 = new JButton();
        panelCenterCh3.setLayout(new GridLayout(2, 1, 2, 2));
        panelCenterCh3.add(panelCenterCh3Button1);
        panelCenterCh3.add(panelCenterCh3Button2);
        //
        JButton panelCenterCh4Button1 = new JButton();
        JButton panelCenterCh4Button2 = new JButton();
        panelCenterCh4.setLayout(new GridLayout(2, 1, 2, 2));
        panelCenterCh4.add(panelCenterCh4Button1);
        panelCenterCh4.add(panelCenterCh4Button2);
        //
        panelCenterCh5.setLayout(new BorderLayout());
        JButton panelCenterCh5Button = new JButton();
        panelCenterCh5.add(panelCenterCh5Button, BorderLayout.CENTER);
        //
        panelCenter.add(panelCenterCh1);
        panelCenter.add(panelCenterCh2);
        panelCenter.add(panelCenterCh3);
        panelCenter.add(panelCenterCh4);
        panelCenter.add(panelCenterCh5);
        //
        panelSouth.setBackground(Color.red.darker());
        panelSouth.setPreferredSize(new Dimension(80, 30));
        //
        panel.setLayout(new BorderLayout(2, 2));
        panel.add(panelNorth, BorderLayout.NORTH);
        panel.add(panelCenter, BorderLayout.CENTER);
        panel.add(panelSouth, BorderLayout.SOUTH);
        //
        scrollPane = new JScrollPane(panel);
        frame.add(scrollPane, BorderLayout.CENTER);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(80, 600));
        frame.setLocation(100, 150);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                ThinLineFrame dlg = new ThinLineFrame();
            }
        });
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • +1 good one. I was actually writing my answer as well but I got annoyed on the [problem that I describe here](http://stackoverflow.com/questions/6072956/how-to-correct-center-gridlayout-using-standard-java-layout-managers) can you @mKorbel do something about that? – Boro May 20 '11 at 13:56
  • Thank you. My primary problems are still not solved, though. 1. How do I make the buttons a fixed size, say 25x25, and still keep the compartment size the same? button.setSize(25, 25) has no effect at all. 2. How do I set the red area's height to `0.05 * frame.getHeight()`, for example? If I do this in the constructor, the red area will not be resized when resizing the window. – tajmahal May 20 '11 at 14:07
  • agreed, then easiest way is use GrigBagLaout (for childs JPanels) and check this examples http://www.java2s.com/Tutorial/Java/0240__Swing/1480__GridBagConstraints.htm how you can really stick (f.e JButton) in JPanel with constraints.anchor = GridBagConstraints.CENTER; – mKorbel May 20 '11 at 14:36
  • You mean put a separate JPanel next to each compartment and put the buttons in there? And how would I go on to make the red areas flexible in height but with a defined ratio (i.e. 1/10th of the entire panel's height? – tajmahal May 20 '11 at 18:45
  • Ah well, disregard that last comment, that's nonsense. I am now trying to replace the outermost BorderLayout with a GridBagLayout. It doesn't work at all however. Any advice? – tajmahal May 20 '11 at 20:23
  • @tajmahal that's two different ideas – mKorbel May 20 '11 at 20:36
  • Ok, I think I got it now. Thanks again for the great code sample! – tajmahal May 21 '11 at 00:46
  • @tajmahal you are welcome, and I forgot one of greatest specifications of topic in this month, anyway +1 for that – mKorbel May 21 '11 at 08:39
2

You should try looking at MigLayout. It's a super flexible LayoutManager that is also very simple.

The code would look something like:

MigLayout layout = new MigLayout("flowy");
panel.setLayoutManager(layout);
panel.add(button1);
panel.adD(button2);
etc..

Try adding debug, flowy to the constructor to get a visual idea of what is going on.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
meverett
  • 921
  • 5
  • 6
  • Can I tell MigLayout to make button1 e.g. 0.05 times as high as button2 so that this ratio is also kept when resizing the window? – tajmahal May 20 '11 at 14:14
  • Yes you can. You can set position relative to other component positions. It's been a little while since I've touched Swing code but it's definately possible and very straightforward. Take a look at the MigLayout cheat sheat for exact details on it – meverett May 20 '11 at 14:29
1

GBC without an anchor, just with plain vanilla GridBagConstraints and preferred size.

Centered JButton with fixed size:

import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JButton;
import javax.swing.JFrame;

public class MainWithFixSize {
    public static void main(String[] argv) throws Exception {
        JFrame frame = new JFrame();
        Container container = frame.getContentPane();
        GridBagLayout gbl = new GridBagLayout();
        container.setLayout(gbl);
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 1;
        gbc.gridy = 1;
        JButton component = new JButton();
        component.setPreferredSize(new Dimension(25, 25));
        gbl.setConstraints(component, gbc);
        container.add(component);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(40, 90));
        frame.pack();
        frame.setVisible(true);
    }

    private MainWithFixSize() {
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
mKorbel
  • 109,525
  • 20
  • 134
  • 319