Search code examples
javaswingjframejpaneljbutton

How to manual set the location of buttons inside a panel in JFrame


Currently, I have this:

Frame

and here's my code:

import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.event.ActionEvent.*;
import java.awt.event.ActionListener.*;
import javax.swing.*;
import javax.swing.JFrame.*;

public class Test extends JFrame //implements ActionListener
{
    //setting private JFrame variables 
    private JMenuBar menu;
    private JMenuItem m1,m2;
    private JFrame f;
    private JPanel panel;
    private JButton btnUnit,btnInfo,btnSearch,btnExit;

    public Test()
    {
        try
        {
            //creating new Jframe variable f
            f = new JFrame();

            //creating new JMenubar
            menu = new JMenuBar();

            //creating new JMenuItem
            m1 = new JMenuItem("File");
            m2 = new JMenuItem("Exit");

            menu.add(m1);
            menu.add(m2);

            panel = new JPanel(new GridLayout(9,1));
            panel.add(menu);
            this.add(panel);

            btnUnit = new JButton("Unit");
            //btnUnit.setLayout(new GridLayout(1,3,100,0));
            btnInfo = new JButton("Information");
            btnSearch = new JButton("Search");
            btnExit = new JButton("Exit");

            panel.add(btnUnit);
            panel.add(btnInfo);
            panel.add(btnSearch);
            panel.add(btnExit); 

            this.setTitle("MyFrame");
            this.setDefaultLookAndFeelDecorated(true);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        
            this.setSize(300,200);
            this.setLocationRelativeTo(null);
            this.setResizable(false);       
            this.setVisible(true);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

    public static void main(String[] a)
    {
        Test test = new Test();  
    }
}

I am a poor person and have small knowledge about java. I want to learn about GUI, so I am doing trial-error in my program. My goal for now is to have a JFrame with Menu on the top and 4 buttons below it, but I do not know how to set the size of the buttons and set their location manually on that panel.

I really want to learn, please, help me. Any comments, suggestions, remarks are accepted and well-appreciated.

This is the output that I am aiming for: Frame Output


Solution

  • There's a number of ways you might be able to achieve this, for example...

    Layout

    import java.awt.EventQueue;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.GridLayout;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JMenuBar;
    import javax.swing.JMenuItem;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.border.EmptyBorder;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
                    JMenuBar menu = new JMenuBar();
    
                    //creating new JMenuItem
                    JMenuItem m1 = new JMenuItem("File");
                    JMenuItem m2 = new JMenuItem("Exit");
    
                    menu.add(m1);
                    menu.add(m2);
    
                    JFrame frame = new JFrame("Testing");
                    frame.setJMenuBar(menu);
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            public TestPane() {
                setLayout(new GridLayout(2, 2));
                add(new FillerPane(new JButton("Unit")));
                add(new FillerPane(new JButton("Information")));
                add(new FillerPane(new JButton("Search")));
                add(new FillerPane(new JButton("Exit")));
            }
    
            public class FillerPane extends JPanel {
    
                public FillerPane(JButton button) {
                    setBorder(new EmptyBorder(10, 10, 10, 10));
                    setLayout(new GridBagLayout());
                    GridBagConstraints gbc = new GridBagConstraints();
                    gbc.gridx = 0;
                    gbc.gridy = 0;
                    gbc.ipady = 20;
                    gbc.fill = GridBagConstraints.HORIZONTAL;
                    gbc.weightx = 1;
                    add(button, gbc);
                }
    
            }
    
        }
    
    }
    

    or...

    Layout

    import java.awt.EventQueue;
    import java.awt.GridLayout;
    import java.awt.Insets;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JMenuBar;
    import javax.swing.JMenuItem;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.border.EmptyBorder;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
                    JMenuBar menu = new JMenuBar();
    
                    //creating new JMenuItem
                    JMenuItem m1 = new JMenuItem("File");
                    JMenuItem m2 = new JMenuItem("Exit");
    
                    menu.add(m1);
                    menu.add(m2);
    
                    JFrame frame = new JFrame("Testing");
                    frame.setJMenuBar(menu);
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            public TestPane() {
                setBorder(new EmptyBorder(10, 10, 10, 10));
                setLayout(new GridLayout(2, 2, 10, 10));
                add(makeButton("Unit"));
                add(makeButton("Information"));
                add(makeButton("Search"));
                add(makeButton("Exit"));
            }
    
            protected JButton makeButton(String text) {
                JButton btn = new JButton(text);
                btn.setMargin(new Insets(10, 10, 10, 10));
                return btn;
            }
    
        }
    
    }
    

    Take a look at Laying Out Components Within a Container for more details

    I was wondering about the menu items, us m1.add(m2); and remove the menu.add(m2);

    Use a JMenuItem, for example...

    JMenuBar mb = new JMenuBar();
    JMenu m = new JMenu("File");
    JMenuItem exit = new JMenuItem("Exit");
    m.add(exit);
    mb.add(m);
    

    Have a look at How to Use Menus for more details