简体   繁体   中英

In Java, is there a way to center a group of buttons with variable size(Using Swing)?

I've been trying to make a GUI like this:

在此处输入图片说明

However, the difficult I've run into is that I need to make the text of the buttons variable- each button should present a different option, which can vary in text length. While this itself is not difficult, I've tried countless different things but I can't get the buttons to center despite their text length. Whatever I try, I always have one of these problems:

  • The buttons don't center (there's space left at the left but they exceed the window at the right)
  • For some reason, the Question and the Goodratio change location based on the button size

I have no clue left how to do this. Does anyone have some useful intuitions on what's the best way to do this? It would be much appreciated.

EDIT: Code of the constructor function(which doesn't center correctly), which I use to set the components, as requested:

    public ButtonPannel(Test test)
{
    super();

    op1Button = new JButton("Option 1");
    op2Button = new JButton("Option 2");
    op3Button = new JButton("Option 3");
    questionText = new JLabel("Question");
    rightAndWrongAmount = new JLabel("rightAndWrongAmount");

    GridBagLayout gridBagLayout = new GridBagLayout();
    gridBagLayout.columnWidths = new int[]{30, 331, 0};
    gridBagLayout.rowHeights = new int[]{16, 0, 134, 35, 16, 0};
    gridBagLayout.columnWeights = new double[]{0.0, 0.0, Double.MIN_VALUE};
    gridBagLayout.rowWeights = new double[]{0.0, 0.0, 1.0, 0.0, 0.0, Double.MIN_VALUE};
    setLayout(gridBagLayout);

    JPanel panel = new JPanel();
    FlowLayout flowLayout = (FlowLayout) panel.getLayout();

    op1Button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
        }
    });

    GridBagConstraints gbc_lblQuestion = new GridBagConstraints();
    gbc_lblQuestion.insets = new Insets(0, 0, 5, 0);
    gbc_lblQuestion.gridx = 1;
    gbc_lblQuestion.gridy = 1;
    add(questionText, gbc_lblQuestion);
    panel.add(op1Button);

    panel.add(op2Button);

    panel.add(op3Button);
    GridBagConstraints gbc_panel = new GridBagConstraints();
    gbc_panel.insets = new Insets(0, 0, 5, 0);
    gbc_panel.gridx = 1;
    gbc_panel.gridy = 3;
    add(panel, gbc_panel);

    GridBagConstraints gbc_lblNewLabel_1 = new GridBagConstraints();
    gbc_lblNewLabel_1.gridx = 1;
    gbc_lblNewLabel_1.gridy = 4;

    add(rightAndWrongAmount, gbc_lblNewLabel_1);

    op1Button.addActionListener(new InputHandler(test));
    op1Button.setActionCommand("1");
    op2Button.addActionListener(new InputHandler(test));
    op2Button.setActionCommand("2");
    op3Button.addActionListener(new InputHandler(test));
    op3Button.setActionCommand("3");

}

The code is generated using WindowBuilder. The problem isn't so much in the code, but more which Layout to use etc.

Layouts are a little bit of black magic and trial and error. Very rarely will a single layout achieve exactly what you want, so you often need to resort to compound layouts (using multiple containers and layouts) to get what you want...

例

So, basically, this is made of a panel, with another panel holding the buttons (and another panel acting as the "pseudo" content to add space)

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
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 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();
                }

                JFrame frame = new JFrame("Testing");
                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 GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;

            add(new JLabel("Question"), gbc);
            gbc.fill = GridBagConstraints.BOTH;
            gbc.weightx = 1;
            gbc.weighty = 1;
            // This is just to act as some psudo context
            add(new FillerPane(), gbc);
            gbc.fill = GridBagConstraints.NONE;
            gbc.weightx = 0;
            gbc.weighty = 0;
            add(makeButtonPane(), gbc);
            add(new JLabel("Goodratio"), gbc);
        }

        public JPanel makeButtonPane() { 
            JPanel panel = new JPanel(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.weightx = 1;
            panel.add(new JButton("Short"));
            panel.add(new JButton("Long, long, long and lobng"));
            panel.add(new JButton("In the middle"));
            return panel;
        }

    }

    public class FillerPane extends JPanel {

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

}

"But I want the buttons to be the same size" I hear you ask, sure, change layouts...

另一个例子

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
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 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();
                }

                JFrame frame = new JFrame("Testing");
                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 GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;

            add(new JLabel("Question"), gbc);
            gbc.fill = GridBagConstraints.BOTH;
            gbc.weightx = 1;
            gbc.weighty = 1;
            // This is just to act as some psudo context
            add(new FillerPane(), gbc);
            gbc.fill = GridBagConstraints.NONE;
            gbc.weightx = 0;
            gbc.weighty = 0;
            add(makeButtonPane(), gbc);
            add(new JLabel("Goodratio"), gbc);
        }

        public JPanel makeButtonPane() { 
            JPanel panel = new JPanel(new GridLayout(1, 0));
            panel.add(new JButton("Short"));
            panel.add(new JButton("Long, long, long and lobng"));
            panel.add(new JButton("In the middle"));
            return panel;
        }

    }

    public class FillerPane extends JPanel {

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

}

You have to look at the layout and think about how each element relates to the others, in terms of what you want them to do, then find the layout managers which are going to help you achieve the end results and combine them together

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