Search code examples
javaswingjbuttonlayout-managergridbaglayout

Is there a more precise way to place my JButtons other than using GridBagConstraints?


package swingtraining;

import static java.awt.Color.BLACK;
import java.awt.GridBagConstraints;
import static java.awt.GridBagConstraints.CENTER;
import static java.awt.GridBagConstraints.NORTH;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class JFrameTest extends JFrame {

    public JFrameTest() {
        setSize(500, 500);
        setTitle("Hello :D");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setResizable(false);
        setVisible(true);
    }

    public static class JPanelTest extends JPanel {

        public JPanelTest() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.ipadx = 100;
            gbc.ipady = 0;
            gbc.anchor = GridBagConstraints.WEST;
            gbc.weightx = 1.0;
            gbc.weighty = 1.0;
            setBackground(BLACK);
            setOpaque(true);
            add(new JButton("Hello"), gbc);
        }
    }

    public static class JButtonTest extends JButton {

        JButtonTest() {
        }
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                JFrameTest T = new JFrameTest();
                JPanelTest Jp1 = new JPanelTest();
                T.add(Jp1);
            }
        });
    }
}

This code works fine, but I don't like how my Button is just placed exactly to the LEFT, with only the ability to change the size (width, height) of the bButton. So I was wondering if there was a more precise way to place things, like maybe just telling Java to place it on the Panel using X Y coordinates or something, like;

JButton.setLocation(200,200);

Any suggestions?


Solution

  • So I was wondering if there was a more precise way to place things, like maybe just telling Java to place it on the Panel using X Y coordinates or something, like;

    You might not appreciate it, but the layout managers are very powerful and very good at their jobs, which mostly reduces your work load and makes your live much, much easier

    GridBagConstraints#insets

    So all I really did was change the anchor constraint to GridBagConstraints.NORTHWEST and added gbc.insets = new Insets(200, 200, 0, 0);

    Example

    The red is coming from the custom glassPane which is painting a dot which is centered at 200x200, but because the JButton doesn't fill its entire area, so I added a ComponentListener to it and it printed out the location when the componentMoved event occurred, which printed out 200x20

    import java.awt.Color;
    import static java.awt.Color.BLACK;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    import java.awt.event.ComponentAdapter;
    import java.awt.event.ComponentEvent;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import static javax.swing.JFrame.EXIT_ON_CLOSE;
    import javax.swing.JPanel;
    
    public class JFrameTest extends JFrame {
    
        public JFrameTest() {
            setSize(500, 500);
            setTitle("Hello :D");
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            setLocationRelativeTo(null);
            setResizable(false);
            JPanel pane = new JPanel() {
                @Override
                public boolean isOpaque() {
                    return false;
                }
    
                @Override
                protected void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    Graphics2D g2d = (Graphics2D) g.create();
                    g2d.setColor(Color.RED);
                    g2d.fillOval(195, 195, 10, 10);
                    g2d.dispose();
                }
    
            };
            setGlassPane(pane);
            pane.setVisible(true);
            setVisible(true);
        }
    
        public static class JPanelTest extends JPanel {
    
            public JPanelTest() {
                setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.ipadx = 100;
                gbc.ipady = 0;
                gbc.anchor = GridBagConstraints.NORTHWEST;
                gbc.insets = new Insets(200, 200, 0, 0);
                gbc.weightx = 1.0;
                gbc.weighty = 1.0;
                setBackground(BLACK);
                setOpaque(true);
                JButton btn = new JButton("Hello");
                btn.addComponentListener(new ComponentAdapter() {
                    @Override
                    public void componentMoved(ComponentEvent e) {
                        System.out.println(btn.getLocation());
                    }
                });
                add(btn, gbc);
            }
        }
    
        public static void main(String args[]) {
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    JFrameTest T = new JFrameTest();
                    JPanelTest Jp1 = new JPanelTest();
                    T.add(Jp1);
                }
            });
        }
    }