data_pi
data_pi

Reputation: 821

Java GUI - How to center a single button

I'm very new to java (I'm used to python).

NOTE: I do want the position to stay in the center even when the gui is resized.

I was wondering how I can center a single button? At the moment, the button is at the top of the gui.

public class main_gui extends JFrame{

    public static void main(String[] args) {

        // Initial window
        JFrame start_frame = new JFrame("P.D");
        start_frame.setSize(1200, 800);
        start_frame.setVisible(true);
        start_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Panel to hold our buttons
        JPanel start_panel = new JPanel();
        start_frame.add(start_panel);


        // Button to initialize everything
        JButton start_button = new JButton("Start");
        // Take out the border around the text
        start_button.setFocusable(false);
        start_panel.add(start_button);
    }
}

Here is what is currently looks like, I just want this button down a bit, to the center.

enter image description here

Upvotes: 2

Views: 18967

Answers (4)

camickr
camickr

Reputation: 324108

There is no need for the panel. Just add the button directly to the frame.

The easiest way is to use a GridBagLayout:

frame.setLayout( new GridBagLayout() );
frame.add(startButton, new GridBagConstraints());

By default the component will be centered horizontally and vertically within the GridBagLayout.

Upvotes: 5

Costis Aivalis
Costis Aivalis

Reputation: 13728

A quick solution would be to set the vertical gap between components of your FlowLayout to half the size of your JFrame:

public class MainGUI {

    static java.awt.Dimension bd;

    public static void main(String[] args) {

        // Initial window
        JFrame start_frame = new JFrame("P.D");
        start_frame.setSize(1200, 800);
        start_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Button to initialize everything
        JButton start_button = new JButton("Start");
        bd = start_button.getPreferredSize();
        // Take out the border around the text
        start_button.setFocusable(false);        

        // Panel to hold our buttons
        java.awt.Dimension d = start_frame.getSize();
        JPanel start_panel = new JPanel(new java.awt.FlowLayout(FlowLayout.CENTER, 0, d.height / 2 - bd.height / 2));
        start_panel.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent evt) {
                JPanel c = (JPanel) evt.getSource();
                c.setLayout(new java.awt.FlowLayout(FlowLayout.CENTER, 0, c.getSize().height / 2 - bd.height / 2));
            }
        });

        start_panel.add(start_button);
        start_frame.add(start_panel);  
        start_frame.setVisible(true);
    }
}

When the size of your JFrame is changed, the ComponentAdapter recalculates the new height and places the button to the new center.

In order to place the button to the vertical center, we calculate the height of your button and subtract its half from the vertical gap.

The horizontal center is automatically applied by the layout.

Your class should not extend JFrame if you instantiate another JFrame inside it and use it.

Class names should be nouns, in mixed case with the first letter of each internal word capitalized.

It is recommended to make your JFrame visible after you have added all widgets to it.

In order to use the SwingUtilities invoker and make your application code cleaner, let your class extend JFrame, write a constructor and call it this way:

public class MainGUIJFrame extends JFrame {

    public MainGUIJFrame() {
        initComponents();
    }

    private void initComponents() {
        setTitle("P.D");
        setSize(1200, 800);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        start_button = new JButton("Start");
        bd = start_button.getPreferredSize();
        // Take out the border around the text
        start_button.setFocusable(false);

        java.awt.Dimension d = getSize();
        start_panel = new JPanel(new java.awt.FlowLayout(FlowLayout.CENTER, 0, d.height / 2 - bd.height / 2));
        start_panel.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent evt) {
                JPanel c = (JPanel) evt.getSource();
                c.setLayout(new java.awt.FlowLayout(FlowLayout.CENTER, 0, c.getSize().height / 2 - bd.height / 2));
            }
        });

        start_panel.add(start_button);
        add(start_panel);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new MainGUIJFrame().setVisible(true);
            }
        });
    }

    private JButton start_button;
    private JPanel start_panel;

    private java.awt.Dimension bd;
}

You keep main simple and small this way, and bd does not have to be static anymore.

Upvotes: 2

Tasos Papastylianou
Tasos Papastylianou

Reputation: 22215

The best way to do it is to use a Layout of your choice and try to make it work using that.

However, if you are sure your window won't be getting resized, or you're happy to deal with such events yourself, you could attempt working without a layout and position the button manually, e.g.:

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import java.awt.Dimension;

public class main_gui {
    public static void main(String[] args) {

        // Initial window
        JFrame start_frame = new JFrame("P.D");
        int FrameWidth = 1200, FrameHeight = 800;
        start_frame.setSize(FrameWidth, FrameHeight);
        start_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Panel to hold our buttons
        JPanel start_panel = new JPanel();
        start_panel.setLayout(null);  // Now working without a layout manager
                                      // i.e, can position things manually.
        start_frame.add(start_panel);

        // Button to initialize everything
        JButton start_button = new JButton("Start");
        start_button.setFocusable(false); // Take out the border around the text
        Dimension size = start_button.getPreferredSize();
        start_button.setBounds( FrameWidth/2  - size.width/2,
                                FrameHeight/2 - size.height/2,
                                size.width,     size.height);
        start_panel.add(start_button);

        // Display the Layout after all components have been added.
        // (adding components after the frame has been set to visible
        //  may result in components not showing up reliably!)
        start_frame.setVisible(true);
    }
}

Upvotes: 0

Shakhar
Shakhar

Reputation: 442

You can use a layout manager like BorderLayout if you want to put the button in the center so that it occupies the whole space in the frame. So, your code will look something like this:

public class main_gui extends JFrame{

    public static void main(String[] args) {

        // Initial window
        JFrame start_frame = new JFrame("P.D");
        start_frame.setSize(1200, 800);
        start_frame.setVisible(true);
        start_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Panel to hold our buttons
        JPanel start_panel = new JPanel();
        start_panel.setLayout(new BorderLayout());
        start_frame.add(start_panel);


        // Button to initialize everything
        JButton start_button = new JButton("Start");
        // Take out the border around the text
        start_button.setFocusable(false);
        start_panel.add(start_button, BorderLayout.CENTER);
    }
}

You may go without using a layout manager. It's a bad practice but it should work. This code will put a small button in the center of the frame:

public class MainGUI {

    public static void main(String[] args) {
        JFrame start_frame = new JFrame("P.D");
        int width = 1200;
        int height = 800;
        start_frame.setSize(width, height);
        start_frame.setVisible(true);
        start_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Panel to hold our buttons
        JPanel start_panel = new JPanel();
        start_panel.setLayout(null);
        start_frame.add(start_panel);


        // Button to initialize everything
        JButton start_button = new JButton("Start");
        buttonWidth = 80;
        buttonHeight = 20;
        start_button.setBounds(new Rectangle((width - buttonWidth)/2, (height - buttonHeight)/2, buttonWidth, buttonHeight));
        start_button.setSize(new Dimension(buttonWidth, buttonHeight));
        start_button.setFocusable(false);
        start_panel.add(start_button);
    }
}

Upvotes: 1

Related Questions