简体   繁体   中英

Java GUI layout cannot quite get it right

I tried a bunch of different layouts but none are giving me the desired effect.

I want something like this:

+-----------------------------+
         Centered Text
+-------+
|Button |
+-------+
+-----------------------------+

In html it might look like this:

<p align="center">Some text</p>
<input type="button" value="Press"/>

The trouble I am having is with certain layouts (BorderLayout) it likes to resize the button to fit. Other layouts (Boxlayout and GroupLayout) will do something like this:

+-----------------------------+
         Centered Text
               +-------+
               |Button |
               +-------+
+-----------------------------+

Even when I have the JLabel aligned to CENTER and the Button aligned to LEFT.

Much appreciation to my helpers.

There are a number layouts that would be able to achieve this, in fact, you might even be able to use BorderLayout and FlowLayout together to do this, but this example simply uses GridBagLayout

在此处输入图片说明

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ExampleLayout {

    public static void main(String[] args) {
        new ExampleLayout();
    }

    public ExampleLayout() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.weightx = 1;

            JLabel center = new JLabel("Centered Text");
            center.setHorizontalAlignment(JLabel.CENTER);
            add(center, gbc);

            gbc.gridy++;
            gbc.fill = GridBagConstraints.NONE;
            gbc.gridwidth = 1;
            gbc.weightx = 0;
            gbc.anchor = GridBagConstraints.WEST;

            JButton button = new JButton("Button");
            add(button, gbc);
        }
    }

}

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

FlowLayout(int align) allows you to define justification. The default is CENTER. If you just left justify the FlowLayout of the panel that contains your button it works without having to use GridBagLayout manually. NetBeans provide an excellent GridBagLayout customizer, but you do not want to touch the code it generates automatically.

在此处输入图片说明

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

public class MyLooks extends JFrame {

    public MyLooks() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        p = new JPanel(new GridLayout(2, 1));
        p1 = new JPanel();
        p2 = new JPanel(new FlowLayout(FlowLayout.LEFT));
        myLabel = new JLabel("this is a label");
        myButton = new JButton("press");
        p1.add(myLabel);
        p2.add(myButton);
        p.add(p1);
        p.add(p2);
        setContentPane(p);
        pack();
    }

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

    private JLabel myLabel;
    private JButton myButton;
    private JPanel p, p1, p2;
}

Although MadProgrammer and Costis Aivalis already answered your question, here is also an answer with MigLayout :

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import net.miginfocom.swing.MigLayout;

public class MigLayoutDemo {
    JFrame frame = new JFrame();
    JPanel panel = new JPanel();

    JLabel label = new JLabel("Centered text");
    JButton button = new JButton("Button");

    public MigLayoutDemo() {
        panel.setLayout(new MigLayout());
        label.setHorizontalAlignment(JLabel.CENTER);
        panel.add(label, "wrap, pushx, growx");
        panel.add(button);

        frame.add(panel);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(MigLayoutDemo::new);
    }

}

Same effect, but this approach is less verbose unlike in case of GridBagLayout and I personally think that MigLayout is easier to use.

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM