我不确定这是否能回答原始发帖者的问题,但希望它对其他 Swing 开发人员有所帮助。
大多数人希望标签和组件对齐,就像我创建的以下对话框一样。
我使用 Swing 布局管理器 GridBagLayout 来创建这种类型的布局。这里没有大量解释,而是创建此对话框的代码。
package com.ggl.business.planner.view;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingConstants;
import com.ggl.business.planner.model.BusinessPlannerModel;
import com.ggl.business.planner.view.extended.EscapeDialog;
import com.ggl.business.planner.view.extended.JFontChooser;
public class OptionsDialog {
protected static final Insets entryInsets = new Insets(0, 10, 4, 10);
protected static final Insets spaceInsets = new Insets(10, 10, 4, 10);
protected static final Insets noInsets = new Insets(0, 0, 0, 0);
protected static final Insets iconInsets = new Insets(0, 4, 0, 0);
protected BusinessPlannerFrame frame;
protected BusinessPlannerModel model;
protected EscapeDialog dialog;
protected JButton activityTextFontButton;
protected JButton connectorTextFontButton;
protected JSpinner borderSizeSpinner;
protected SpinnerNumberModel spinnerNumberModel;
protected boolean okPressed;
public OptionsDialog(BusinessPlannerModel model, BusinessPlannerFrame frame) {
this.model = model;
this.frame = frame;
createPartControl();
}
protected void createPartControl() {
dialog = new EscapeDialog();
dialog.setTitle("Business Planner Options");
dialog.setLayout(new GridBagLayout());
int gridy = 0;
gridy = createBorderFields(gridy);
gridy = createFontFields(gridy);
gridy = createButtonFields(gridy);
dialog.pack();
dialog.setBounds(dialogBounds());
dialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
dialog.setVisible(true);
}
protected int createBorderFields(int gridy) {
JLabel borderSizeLabel = new JLabel("Border size:");
borderSizeLabel.setHorizontalAlignment(SwingConstants.LEFT);
addComponent(dialog, borderSizeLabel, 0, gridy, 1, 1, spaceInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
spinnerNumberModel = new SpinnerNumberModel(model.getActivityBorder(), 1, 5, 1);
borderSizeSpinner = new JSpinner(spinnerNumberModel);
addComponent(dialog, borderSizeSpinner, 1, gridy++, 4, 1, spaceInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
return gridy;
}
protected int createFontFields(int gridy) {
JLabel boxtextFontLabel = new JLabel("Activity text font:");
boxtextFontLabel.setHorizontalAlignment(SwingConstants.LEFT);
addComponent(dialog, boxtextFontLabel, 0, gridy, 1, 1, spaceInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
Font font = model.getActivityFont();
activityTextFontButton = new JButton(getFontText(font));
activityTextFontButton.setFont(font);
activityTextFontButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
JFontChooser fontChooser = new JFontChooser();
fontChooser.setSelectedFont(model.getActivityFont());
int result = fontChooser.showDialog(dialog);
if (result == JFontChooser.OK_OPTION) {
Font font = fontChooser.getSelectedFont();
String text = getFontText(font);
model.setActivityFont(font);
activityTextFontButton.setText(text);
activityTextFontButton.setFont(font);
JButton dummy = new JButton(text);
setButtonSizes(activityTextFontButton,
connectorTextFontButton, dummy);
dialog.validate();
dialog.pack();
}
}
});
addComponent(dialog, activityTextFontButton, 1, gridy++, 4, 1, spaceInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
JLabel connectortextFontLabel = new JLabel("Connector text font:");
connectortextFontLabel.setHorizontalAlignment(SwingConstants.LEFT);
addComponent(dialog, connectortextFontLabel, 0, gridy, 1, 1, spaceInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
font = model.getConnectorFont();
connectorTextFontButton = new JButton(getFontText(font));
connectorTextFontButton.setFont(font);
connectorTextFontButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
JFontChooser fontChooser = new JFontChooser();
fontChooser.setSelectedFont(model.getConnectorFont());
int result = fontChooser.showDialog(dialog);
if (result == JFontChooser.OK_OPTION) {
Font font = fontChooser.getSelectedFont();
String text = getFontText(font);
model.setConnectorFont(font);
connectorTextFontButton.setText(text);
connectorTextFontButton.setFont(font);
JButton dummy = new JButton(text);
setButtonSizes(activityTextFontButton,
connectorTextFontButton, dummy);
dialog.validate();
dialog.pack();
}
}
});
addComponent(dialog, connectorTextFontButton, 1, gridy++, 4, 1, spaceInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
setButtonSizes(activityTextFontButton, connectorTextFontButton);
return gridy;
}
protected String getFontText(Font font) {
StringBuilder builder = new StringBuilder();
builder.append(font.getName());
builder.append(", ");
builder.append(font.getSize());
builder.append(" points, ");
if (font.isPlain()) {
builder.append("plain");
} else if (font.isBold()) {
builder.append("bold ");
} else if (font.isItalic()) {
builder.append("italic");
}
return builder.toString();
}
protected int createButtonFields(int gridy) {
JPanel buttondrawingPanel = new JPanel();
buttondrawingPanel.setLayout(new FlowLayout());
JButton okButton = new JButton("OK");
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
//TODO Add edits to make sure fields are filled correctly
setModel();
okPressed = true;
dialog.setVisible(false);
}
});
dialog.setOkButton(okButton);
buttondrawingPanel.add(okButton);
JButton cancelButton = new JButton("Cancel");
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
okPressed = false;
dialog.setVisible(false);
}
});
buttondrawingPanel.add(cancelButton);
setButtonSizes(okButton, cancelButton);
addComponent(dialog, buttondrawingPanel, 0, gridy++, 5, 1, spaceInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
return gridy;
}
protected void addComponent(Container container, Component component,
int gridx, int gridy, int gridwidth, int gridheight,
Insets insets, int anchor, int fill) {
GridBagConstraints gbc = new GridBagConstraints(gridx, gridy,
gridwidth, gridheight, 1.0D, 1.0D, anchor, fill, insets, 0, 0);
container.add(component, gbc);
}
protected void setButtonSizes(JButton ... buttons) {
Dimension preferredSize = new Dimension();
for (JButton button : buttons) {
Dimension d = button.getPreferredSize();
preferredSize = setLarger(preferredSize, d);
}
for (JButton button : buttons) {
button.setPreferredSize(preferredSize);
}
}
protected Dimension setLarger(Dimension a, Dimension b) {
Dimension d = new Dimension();
d.height = Math.max(a.height, b.height);
d.width = Math.max(a.width, b.width);
return d;
}
protected void setModel() {
model.setActivityBorder(spinnerNumberModel.getNumber().intValue());
}
protected Rectangle dialogBounds() {
int margin = 200;
Rectangle bounds = dialog.getBounds();
Rectangle f = frame.getFrame().getBounds();
bounds.x = f.x + margin;
bounds.y = f.y + margin;
return bounds;
}
public boolean isOkPressed() {
return okPressed;
}
}
我扩展的 EscapeDialog 类只允许我使用 Esc 键关闭对话框,就像我左键单击取消按钮一样。
有两点我要注意。第一个是 addComponent 方法,它简化了向 GridBagLayout 添加组件的过程。
第二个是 setButtonSizes 方法,它使所有按钮大小统一。即使它们是 JButton 组件,而不是 JTextField 组件,如果您想让 JTextField 组件大小相同,您也可以执行类似的操作。