java GUI布局建议
java GUI layout suggestion
public class AFS {
public JPanel afs(final Fields input){
JPanel titlePanel = new JPanel();
//Title fields
JLabel afs = new JLabel("Statement", Label.LEFT);
Label mm = new Label("month ", Label.LEFT);
Label my = new Label("Year ", Label.LEFT);
//first line
titlePanel.add(afs);
titlePanel.add(mm);
titlePanel.add(input.MENTRY);
titlePanel.add(my);
titlePanel.add(input.YENTRY);
titlePanel.setPreferredSize(null);
//Left Panels
JPanel sb = new JPanel();
JPanel entry = new JPanel();
entry.setLayout(new BoxLayout(entry, BoxLayout.Y_AXIS));
entry.setAlignmentX(Component.LEFT_ALIGNMENT);
entry.add(new Label("Service "));
entry.add(input.s);
entry.add(new Label("Amount "));
entry.add(input.a);
entry.add(new Label("Counter "));
entry.add(input.o);
entry.add(new Label("Division "));
entry.add(input.d);
sb.add(entry);
JPanel holderPanel = new JPanel();
holderPanel.setLayout(new BoxLayout(holderPanel, BoxLayout.Y_AXIS));
holderPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
holderPanel.add(titlePanel);
holderPanel.add(sb);
JButton start = new JButton("Save Current");
start.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ScriptAction action = new ScriptAction();
action.saveAll(input,1);
}
});
holderPanel.add(start);
return holderPanel;
}
我有上面代码的简短版本。
当前布局如下所示:
但我希望布局看起来像(绘画编辑)。
我已经尝试使用 gridLayout 作为条目进行交换,它将显示 2 行,但 gridlayout 仍会将所有内容居中对齐(包括标题和 header)。此外,按钮跨度将跨越整个底部。我想知道是否有任何建议的方法可以做到这一点?
您需要使用 layout managers 的组合来实现所需的输出:
调整大小前/调整大小后
在这种情况下有 3 个主要部分:
- 顶部窗格(使用
Box
将一些文本左对齐,一些文本右对齐)
- 中间窗格(使用
GridBagLayout
将组件放置在图像中,也许 GridLayout
使用适当的插图也可以工作)
- 底部窗格(使用默认
JPanel
的布局:FlowLayout
)
顶部窗格也使用 2 个 JPanel
,第一个单独用于标签 Statement
,另一个 FlowLayout
与其他 4 个组件右对齐,如per this answer BoxLayout
不符合我们 JTextField
的首选尺寸。因此,解决方法是将它们包装在另一个 JPanel
中,然后将 JPanel
与 Statement 标签一起包装。
中间窗格也出现了类似的问题,它需要使用 2 个 JPanel
s:一个用于包裹在另一个更大的窗格中的字段,该窗格包含它和底部的 JButton
(Save Current
).我们可以通过添加带有 gridx = 2
的 JButton
和带有 counter
和 division
标签的 gridy = 2
以及 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 组件有问题。
public class AFS {
public JPanel afs(final Fields input){
JPanel titlePanel = new JPanel();
//Title fields
JLabel afs = new JLabel("Statement", Label.LEFT);
Label mm = new Label("month ", Label.LEFT);
Label my = new Label("Year ", Label.LEFT);
//first line
titlePanel.add(afs);
titlePanel.add(mm);
titlePanel.add(input.MENTRY);
titlePanel.add(my);
titlePanel.add(input.YENTRY);
titlePanel.setPreferredSize(null);
//Left Panels
JPanel sb = new JPanel();
JPanel entry = new JPanel();
entry.setLayout(new BoxLayout(entry, BoxLayout.Y_AXIS));
entry.setAlignmentX(Component.LEFT_ALIGNMENT);
entry.add(new Label("Service "));
entry.add(input.s);
entry.add(new Label("Amount "));
entry.add(input.a);
entry.add(new Label("Counter "));
entry.add(input.o);
entry.add(new Label("Division "));
entry.add(input.d);
sb.add(entry);
JPanel holderPanel = new JPanel();
holderPanel.setLayout(new BoxLayout(holderPanel, BoxLayout.Y_AXIS));
holderPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
holderPanel.add(titlePanel);
holderPanel.add(sb);
JButton start = new JButton("Save Current");
start.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ScriptAction action = new ScriptAction();
action.saveAll(input,1);
}
});
holderPanel.add(start);
return holderPanel;
}
我有上面代码的简短版本。
当前布局如下所示:
但我希望布局看起来像(绘画编辑)。
我已经尝试使用 gridLayout 作为条目进行交换,它将显示 2 行,但 gridlayout 仍会将所有内容居中对齐(包括标题和 header)。此外,按钮跨度将跨越整个底部。我想知道是否有任何建议的方法可以做到这一点?
您需要使用 layout managers 的组合来实现所需的输出:
在这种情况下有 3 个主要部分:
- 顶部窗格(使用
Box
将一些文本左对齐,一些文本右对齐) - 中间窗格(使用
GridBagLayout
将组件放置在图像中,也许GridLayout
使用适当的插图也可以工作) - 底部窗格(使用默认
JPanel
的布局:FlowLayout
)
顶部窗格也使用 2 个 JPanel
,第一个单独用于标签 Statement
,另一个 FlowLayout
与其他 4 个组件右对齐,如per this answer BoxLayout
不符合我们 JTextField
的首选尺寸。因此,解决方法是将它们包装在另一个 JPanel
中,然后将 JPanel
与 Statement 标签一起包装。
中间窗格也出现了类似的问题,它需要使用 2 个 JPanel
s:一个用于包裹在另一个更大的窗格中的字段,该窗格包含它和底部的 JButton
(Save Current
).我们可以通过添加带有 gridx = 2
的 JButton
和带有 counter
和 division
标签的 gridy = 2
以及 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 组件有问题。