4

I'm trying to put components into panels having different sizes. But, I realized that GridLayout divides the parts with same sizes. How can it be accomplished as explained below image

enter image description here

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

class PanelDemo {

    PanelDemo() {

        // Create a new JFrame container. Use the default
        // border layout.
        JFrame jfrm = new JFrame("Use Three JPanels with Different Sizes");

        // Specify FlowLayout manager.
        jfrm.getContentPane().setLayout(new GridLayout(1, 3));

        // Give the frame an initial size.
        jfrm.setSize(900, 300);

        // Terminate the program when the user closes the application.
        jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Create the first JPanel.
        JPanel jpnl = new JPanel();

        jpnl.setLayout(new GridLayout(2, 4));

        // Set the preferred size of the first panel.
        jpnl.setPreferredSize(new Dimension(500, 300));

        // Make the panel opaque.
        jpnl.setOpaque(true);

        // Add a blue border to the panel.
        jpnl.setBorder(
                BorderFactory.createLineBorder(Color.BLUE));

        // Create the second JPanel.
        JPanel jpnl2 = new JPanel();

        //jpnl2.setLayout(new FlowLayout());
        // Set the preferred size of the second panel.
        jpnl2.setPreferredSize(new Dimension(300, 300));

        // Make the panel opaque.
        jpnl2.setOpaque(true);

        jpnl2.setBorder(
                BorderFactory.createLineBorder(Color.RED));

        JPanel jpnl3 = new JPanel();
        jpnl3.setOpaque(true);
        jpnl3.setPreferredSize(new Dimension(100, 300));
        jpnl3.setBorder(
                BorderFactory.createLineBorder(Color.ORANGE));

        // Add the panels to the frame.
        jfrm.getContentPane().add(jpnl);
        jfrm.getContentPane().add(jpnl3);
        jfrm.getContentPane().add(jpnl2);

        // Display the frame.
        jfrm.setVisible(true);
    }

    public static void main(String args[]) {
        // Create the frame on the event dispatching thread.
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new PanelDemo();
            }
        });
    }
}
swinger
  • 63
  • 1
  • 5
  • 1
    `BorderLayout` using `LINE_START`, `CENTER` & `LINE_END` constraints could do that. But if the GUI is resizable, the center panel will get the extra space.. – Andrew Thompson Aug 02 '16 at 20:40
  • BTW - what is in each panel? If 'components' it is best to allow the layout used for the panel to provide hints as to the preferred size, as opposed to explicitly setting it.. Then instead of calling `jfrm.setSize(900, 300);` - just call `jfrm.pack();` (after all of the components are added) .. – Andrew Thompson Aug 02 '16 at 20:43
  • 1
    BoxLayout? GridBagLayout? Read the Swing tutorial on [Layout Managers](http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html). Each layout manager has different rules for resizing as the frame size is changed. Whatever layout you use is dependent on your exact requirements. Play with each layout manager and then decide what is best for your requirement. – camickr Aug 02 '16 at 20:44
  • I will put buttons with gridlayout(2,4) into first, the second is just for space to show little bit blank area and third is again buttons gridlayout(2,2). Should I always / generally use pack instead of setSize? @AndrewThompson – swinger Aug 03 '16 at 06:42
  • `pack()` will make the GUI the size it needs to be in order to accommodate the components & the frame decorations. `setSize(..)` is gust a guess as to what that size should be. From your descriptionit is obvious that the 2nd panel is not needed. It could be achieved using an `EmptyBorder` applied to the first panel. Give me a few minutes & I'll create the layout.. – Andrew Thompson Aug 03 '16 at 06:50

2 Answers2

3

You could use FlowLayout but if they resize your frame then it will wrap the panels.

Jayfray
  • 415
  • 3
  • 12
  • FlowLayout has a horizontal gap you can set to zero. See the javadoc: http://docs.oracle.com/javase/8/docs/api/java/awt/FlowLayout.html#FlowLayout-int-int-int- – Jayfray Aug 03 '16 at 12:40
3

enter image description here

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

public class TwoPanelWithButtonsLayout {

    private JComponent ui = null;
    private Insets buttonMargin = new Insets(10,10,10,10);

    TwoPanelWithButtonsLayout() {
        initUI();
    }

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

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

        int gap = 5;

        JPanel buttons1 = new JPanel(new GridLayout(2, 4, gap, gap));
        // 50 is the gap on right, alter as needed
        buttons1.setBorder(new EmptyBorder(0, 0, 0, 50)); 
        for (int ii=1; ii<9; ii++) {
            buttons1.add(getBigButton("" + ii));
        }
        ui.add(buttons1, BorderLayout.CENTER);

        JPanel buttons2 = new JPanel(new GridLayout(2, 2, gap, gap));
        for (int ii=1; ii<5; ii++) {
            buttons2.add(getBigButton("" + ii));
        }
        ui.add(buttons2, BorderLayout.LINE_END);
    }

    private JButton getBigButton(String text) {
        JButton b = new JButton(text);
        Font f = b.getFont();
        b.setFont(f.deriveFont(f.getSize()*3f));
        b.setMargin(buttonMargin);
        return b;
    }

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

                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
  • By the way, do you prefer a form builder(GUI maker of an ide) or hand-writing to make GUI? If you prefer form builder, could you tell me what you are using ? – swinger Aug 03 '16 at 07:57
  • I make my GUIs by hand. Form builders are good for prototyping, but not much else. Further, to use them effectively you need to understand how to use & combine layouts in any case. – Andrew Thompson Aug 03 '16 at 08:27
  • thanks for your helps but I need a little more. I have edited my question. Could you take a glance? – swinger Aug 03 '16 at 08:35
  • *"I have edited my question"* Better to ask a new question. Feel free to base it on my answer, if the approach is relevant to the new question. – Andrew Thompson Aug 03 '16 at 08:36
  • Okay. It is here: http://stackoverflow.com/questions/38738784/java-swing-gui-doesnt-seem – swinger Aug 03 '16 at 08:50