您需要使用layout managers 的组合来实现所需的输出:
调整大小前/调整大小后
在这种情况下,有 3 个主要部分:
- 顶部窗格(使用
Box 对齐左侧的一些文本和右侧的一些文本)
- 中间窗格(使用
GridBagLayout 来定位图像中的组件,也许GridLayout 带有适当的插图也可以工作)
- 底部窗格(使用默认
JPanel 的布局:FlowLayout)
顶部窗格也使用 2 个 JPanels,第一个用于标签 Statement,其他 4 个组件与 FlowLayout 右侧对齐,根据 this answer BoxLayout 确实不尊重我们JTextFields 的首选大小。因此,一种解决方法是将它们包装在另一个 JPanel 中,然后将 JPanel 与 Statement 标签一起包装。
中间窗格也出现了类似的问题,它需要使用 2 个JPanels:一个用于包裹在另一个更大的包含它的字段中,JButton 在底部 (Save Current)。我们可以通过将JButton 与gridx = 2 和gridy = 2 与counter 和division 标签和gridx = 3 和gridx = 4 上的字段分别添加(而不是2 & 3)来实现类似的输出,但是然后,我们需要添加 gbc.insets 以在顶部和底部添加具有高值的插图...由您决定使用哪一个 :)
产生上述输出的代码如下:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class FormSample {
private JFrame frame;
private JPanel topRightPane;
private JPanel centerPane;
private JPanel centerWithButtonPane;
private JPanel buttonsPane;
private JTextField monthField;
private JTextField yearField;
private JTextField serviceField;
private JTextField amountField;
private JTextField counterField;
private JTextField divisionField;
private static final int LEFT_MARGIN = 50; //Increase / Decrease to add extra space between components
private static final int RIGHT_MARGIN = LEFT_MARGIN;
//Change insets accordingly to add extra space between components (top, left, bottom, right)
private static final Insets leftInsets = new Insets(0, LEFT_MARGIN, 0, 0);
private static final Insets rightInsets = new Insets(0, 0, 0, RIGHT_MARGIN);
private static final Insets defaultInsets = new Insets(0, 0, 0, 0);
private JButton saveCurrentButton;
private JButton saveAllButton;
private JButton resetButton;
public static void main(String[] args) {
SwingUtilities.invokeLater(new FormSample()::createAndShowGui);
}
private void createAndShowGui() {
frame = new JFrame(getClass().getSimpleName());
monthField = new JTextField(10);
yearField = new JTextField(10);
serviceField = new JTextField(10);
amountField = new JTextField(10);
counterField = new JTextField(10);
divisionField = new JTextField(10);
saveCurrentButton = new JButton("Save Current");
saveAllButton = new JButton("Save all");
resetButton = new JButton("Reset");
buttonsPane = new JPanel();
topRightPane = new JPanel();
topRightPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
topRightPane.add(new JLabel("Month"));
topRightPane.add(monthField);
topRightPane.add(new JLabel("Year"));
topRightPane.add(yearField);
centerWithButtonPane = new JPanel();
centerWithButtonPane.setLayout(new BoxLayout(centerWithButtonPane, BoxLayout.PAGE_AXIS));
Box box = Box.createHorizontalBox();
box.add(new JLabel("Statement"));
box.add(Box.createHorizontalGlue());
box.add(topRightPane);
centerPane = new JPanel();
centerPane.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = defaultInsets;
centerPane.add(new JLabel("Service"), gbc);
gbc.gridx = 1;
gbc.insets = rightInsets;
centerPane.add(serviceField, gbc);
gbc.gridx = 2;
gbc.insets = leftInsets;
centerPane.add(new JLabel("Counter"), gbc);
gbc.gridx = 3;
gbc.insets = defaultInsets;
centerPane.add(counterField, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.insets = defaultInsets;
centerPane.add(new JLabel("Amount"), gbc);
gbc.gridx = 1;
gbc.insets = rightInsets;
centerPane.add(amountField, gbc);
gbc.gridx = 2;
gbc.insets = leftInsets;
centerPane.add(new JLabel("Division"), gbc);
gbc.gridx = 3;
gbc.insets = defaultInsets;
centerPane.add(divisionField, gbc);
saveCurrentButton.setAlignmentX(Component.CENTER_ALIGNMENT); //Force centered alignment for our JButton
centerWithButtonPane.add(centerPane);
centerWithButtonPane.add(saveCurrentButton);
buttonsPane.add(saveAllButton);
buttonsPane.add(resetButton);
frame.add(box, BorderLayout.NORTH);
frame.add(centerWithButtonPane, BorderLayout.CENTER);
frame.add(buttonsPane, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
另外请遵循@SergiyMedvynskyy 给出的建议,不要混合 AWT 和 Swing 组件(即 JTextField 和 TextField),并且只使用 Swing 组件,因为 AWT 有问题。