Pergunta

I'm trying to figure out the best way to align 2 sets of items in the center of a panel in a Java Swing application. The panel is in the North position of a BorderLayout whose width is determined by the JTextField in the Center position of the layout. The problem I'm having is, I have a set of labels and smaller text fields that I want to center so that the end of the label and the start of the first text field meet at the center of the panel.

I've tried GroupLayout, but ended up with the following result: enter image description here

Note: The 2 text fields separated by a + are in a sub-panel.

What I'm trying to achieve is the following: enter image description here

Apparently I'm either missing something, or this is far more complicated than necessary to do. I actually run into this issue a LOT! I'm surprised there isn't a special grid layout specifically for this.

Trying to do this with a GridLayout resulted in this: enter image description here

So... what IS the easiest way to get the layout I'm looking for (second image)?

GroupLayout example code below:

    JFrame frame = new JFrame();
    JPanel panel = new JPanel(new BorderLayout());
    frame.setContentPane(panel);

    JPanel longText = new JPanel();
    JPanel shortText = new JPanel();
    JPanel mediumText = new JPanel();

    longText.add(new TextField(5));
    longText.add(new JLabel("+"));
    longText.add(new TextField(5));
    shortText.add(new TextField(5));
    shortText.add(new JLabel("+"));
    shortText.add(new TextField(5));
    mediumText.add(new TextField(5));
    mediumText.add(new JLabel("+"));
    mediumText.add(new TextField(5));

    JLabel lExample = new JLabel("Long text example:");
    JLabel sExample = new JLabel("Short:");
    JLabel mExample = new JLabel("Medium Example:");

    JPanel subPanel = new JPanel();
    GroupLayout layout = new GroupLayout(subPanel);
    subPanel.setLayout(layout);
    layout.setHorizontalGroup(layout.createSequentialGroup()
        .addGroup(layout.createParallelGroup(Alignment.CENTER)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(Alignment.TRAILING)
                    .addComponent(lExample)
                    .addComponent(sExample)
                    .addComponent(mExample))
                .addGroup(layout.createParallelGroup(Alignment.TRAILING)
                    .addComponent(longText)
                    .addComponent(shortText)
                    .addComponent(mediumText))))
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER))
    );
    layout.setVerticalGroup(layout.createSequentialGroup()
        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
            .addComponent(lExample)
            .addComponent(longText))
        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
            .addComponent(sExample)
            .addComponent(shortText))
        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
            .addComponent(mExample).addComponent(mediumText))
    );

    JTextArea textArea = new JTextArea() {
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(600,300);
        }
    };
    textArea.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
    textArea.setLineWrap(true);
    textArea.setWrapStyleWord(true);
    textArea.setAutoscrolls(true);

    panel.add(subPanel,BorderLayout.NORTH);
    panel.add(textArea,BorderLayout.CENTER);

    frame.pack();
    frame.setVisible(true);
Foi útil?

Solução

Consider using a GridBagLayout, as it gives you a lot more control over the placement of individual components and respects the preferred size of the components where it can (unless you override them through the use of the GridBagConstraints)

GridBagLayout

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class LayoutExample {

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

    public LayoutExample() {
        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() {
            JLabel longText = new JLabel("Long Text Example");
            JLabel shortText = new JLabel("Short Example");
            JLabel medText = new JLabel("Medium Example");

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.anchor = GridBagConstraints.EAST;
            add(longText, gbc);
            addFields(gbc);

            gbc.gridx = 0;
            gbc.gridy++;
            gbc.anchor = GridBagConstraints.EAST;
            add(shortText, gbc);
            addFields(gbc);

            gbc.gridx = 0;
            gbc.gridy++;
            gbc.anchor = GridBagConstraints.EAST;
            add(medText, gbc);
            addFields(gbc);
        }

        protected void addFields(GridBagConstraints gbc) {
            JTextField field1 = new JTextField("0", 5);
            field1.setEnabled(false);
            gbc.anchor = GridBagConstraints.CENTER;
            gbc.gridx++;
            add(field1, gbc);
            gbc.gridx++;
            gbc.insets = new Insets(0, 4, 0, 4);
            add(new JLabel("+"), gbc);
            JTextField field2 = new JTextField(5);
            gbc.gridx++;
            add(field2, gbc);
        }

    }

}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top