我最近开始学习如何用Java编写代码,手工编写。 我正在尝试制作一个GUI,用于作业,但我正在努力将四个标签附加到网格格式的四个文本字段中。
文本字段位于面板内的面板中。所以我可以拥有按钮旁边的字段。
我真的很困惑如何离开我的位置。因为我希望每个标签都放在每个文本字段的左侧。所以"训练"在文本字段旁边的左侧" On"和" Train Moving"标签位于文本字段的左侧" off"。等等。我对此非常感兴趣,所以非常感谢任何帮助,谢谢。我发布的代码目前有效。
修改的
因原因而删除代码
答案 0 :(得分:1)
我对GridBagLayout的每个实际例子都很复杂。这是我所拥有的最简单,真实的例子。该对话框在BoxLayout中有一个GridBagLayout。该按钮位于使用FlowLayout
的JPanel中
这是代码:
package com.ggl.sudoku.solver.view;
import java.awt.Component;
import java.awt.Container;
import java.awt.FlowLayout;
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.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class SolutionDialog {
protected static final Insets buttonInsets = new Insets(10, 10, 0, 10);
private int singleCount;
private int guessCount;
private long elapsedTime;
private JDialog dialog;
private SudokuFrame frame;
public SolutionDialog(SudokuFrame frame, int singleCount, int guessCount,
long elapsedTime) {
this.frame = frame;
this.singleCount = singleCount;
this.guessCount = guessCount;
this.elapsedTime = elapsedTime;
createPartControl();
}
private void createPartControl() {
dialog = new JDialog(frame.getFrame(), "Statistics");
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
JPanel resultsPanel = new JPanel();
resultsPanel.setLayout(new GridBagLayout());
int gridy = 0;
JLabel singleCountLabel = new JLabel("Cells with one possible number:");
addComponent(resultsPanel, singleCountLabel, 0, gridy, 1, 1,
buttonInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
String s = singleCount + " cells";
JLabel singleCountString = new JLabel(s);
addComponent(resultsPanel, singleCountString, 1, gridy++, 1, 1,
buttonInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
JLabel guessCountLabel = new JLabel("Cells where the solver guessed:");
addComponent(resultsPanel, guessCountLabel, 0, gridy, 1, 1,
buttonInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
s = guessCount + " cells";
JLabel guessCountString = new JLabel(s);
addComponent(resultsPanel, guessCountString, 1, gridy++, 1, 1,
buttonInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
JLabel elapsedTimeLabel = new JLabel("Elapsed Time:");
addComponent(resultsPanel, elapsedTimeLabel, 0, gridy, 1, 1,
buttonInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
s = elapsedTime + " milliseconds";
JLabel elapsedTimeString = new JLabel(s);
addComponent(resultsPanel, elapsedTimeString, 1, gridy++, 1, 1,
buttonInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
mainPanel.add(resultsPanel);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout());
JButton okButton = new JButton("OK");
okButton.setAlignmentX(JButton.RIGHT_ALIGNMENT);
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
dialog.setVisible(false);
dialog.dispose();
}
});
buttonPanel.add(okButton);
mainPanel.add(buttonPanel);
dialog.add(mainPanel);
dialog.pack();
dialog.setBounds(getBounds());
dialog.setVisible(true);
}
private 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 Rectangle getBounds() {
Rectangle f = frame.getBounds();
Rectangle d = dialog.getBounds();
d.x = f.x + (f.width - d.width) / 2;
d.y = f.y + (f.height - d.height) / 2;
return d;
}
}
在addComponent方法中,我为每个Swing组件创建一个新的GridBagConstraints。我这样做是因为我不喜欢记住默认值。我更喜欢为每个Swing组件指定所有约束。
这些Swing组件创建了一个JDialog,但在创建JPanel时会应用相同的原则。
如果您想了解整个Swing应用程序如何组合在一起,请阅读我的文章Sudoku Solver Swing GUI。
这是另一个更复杂的例子,但它包含了JTextFields。
以下是创建输入面板的代码:
package com.ggl.envelopes.view;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import com.ggl.envelopes.model.Address;
import com.ggl.envelopes.model.EnvelopeModel;
import com.ggl.envelopes.model.State;
public class AddressPanel {
private static final Insets entryInsets =
new Insets(0, 10, 4, 10);
private static final Insets spaceInsets =
new Insets(10, 10, 4, 10);
private Address currentAddress;
private AddressComboBoxItemListener listener;
private DefaultComboBoxModel<Address> addressComboBoxModel;
private DefaultComboBoxModel<State> stateComboBoxModel;
private EnvelopeModel model;
private JButton updateButton;
private JButton deleteButton;
private JComboBox<Address> addressComboBox;
private JComboBox<State> stateComboBox;
private JLabel messageLabel;
private JPanel mainPanel;
private JTextField nameField;
private JTextField address1Field;
private JTextField address2Field;
private JTextField cityField;
private JTextField zip5Field;
private JTextField zip4Field;
public AddressPanel(EnvelopeModel model) {
this.model = model;
this.listener = new AddressComboBoxItemListener();
this.addressComboBoxModel =
new DefaultComboBoxModel<Address>();
this.stateComboBoxModel =
new DefaultComboBoxModel<State>();
createPartControl();
}
private void createPartControl() {
mainPanel = new JPanel();
mainPanel.setLayout(new GridBagLayout());
int gridy = 0;
if (model.getAddresses().size() > 0) {
gridy = createAddressComboBox(gridy);
}
gridy = createAddressControl(gridy);
}
private int createAddressComboBox(int gridy) {
JLabel addressesLabel = new JLabel("Addresses:");
addressesLabel.setHorizontalAlignment(JLabel.LEFT);
addComponent(mainPanel, addressesLabel, 0, gridy,
1, 1, spaceInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
buildAddressComboBoxModel();
addressComboBox = new JComboBox<Address>(addressComboBoxModel);
addressComboBox.addItemListener(listener);
addComponent(mainPanel, addressComboBox, 1, gridy++,
4, 1, spaceInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
return gridy;
}
private int createAddressControl(int gridy) {
JLabel nameLabel = new JLabel("Name:");
nameLabel.setHorizontalAlignment(JLabel.LEFT);
addComponent(mainPanel, nameLabel, 0, gridy,
1, 1, spaceInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
nameField = new JTextField(30);
nameLabel.setLabelFor(nameField);
addComponent(mainPanel, nameField, 1, gridy++,
4, 1, spaceInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
JLabel address1Label = new JLabel("Address:");
address1Label.setHorizontalAlignment(JLabel.LEFT);
addComponent(mainPanel, address1Label, 0, gridy,
1, 1, entryInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
address1Field = new JTextField(30);
address1Label.setLabelFor(address1Field);
addComponent(mainPanel, address1Field, 1, gridy++,
4, 1, entryInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
JLabel address2Label = new JLabel(" ");
address2Label.setHorizontalAlignment(JLabel.LEFT);
addComponent(mainPanel, address2Label, 0, gridy,
1, 1, entryInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
address2Field = new JTextField(30);
address2Label.setLabelFor(address2Field);
addComponent(mainPanel, address2Field, 1, gridy++,
4, 1, entryInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
JLabel dummyLabel = new JLabel(" ");
dummyLabel.setHorizontalAlignment(JLabel.LEFT);
addComponent(mainPanel, dummyLabel, 0, gridy,
1, 1, entryInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
cityField = new JTextField(10);
dummyLabel.setLabelFor(cityField);
addComponent(mainPanel, cityField, 1, gridy,
1, 1, entryInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
buildStateComboBoxModel();
stateComboBox = new JComboBox<State>(stateComboBoxModel);
stateComboBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
if (event.getActionCommand()
.equals("comboBoxEdited")) {
String s = stateComboBox.getSelectedItem()
.toString();
State t = model.getStateByAbbreviation(s);
if (t != null) {
stateComboBox.setSelectedItem(t);
}
}
}
});
stateComboBox.setEditable(true);
addComponent(mainPanel, stateComboBox, 2, gridy,
1, 1, entryInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
zip5Field = new JTextField(6);
addComponent(mainPanel, zip5Field, 3, gridy,
1, 1, entryInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
zip4Field = new JTextField(6);
addComponent(mainPanel, zip4Field, 4, gridy++,
1, 1, entryInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
messageLabel = new JLabel(" ");
messageLabel.setHorizontalAlignment(JLabel.LEFT);
addComponent(mainPanel, messageLabel, 0, gridy++,
5, 1, entryInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
JPanel buttonPanel = createButtonPanel();
addComponent(mainPanel, buttonPanel, 0, gridy++,
5, 1, spaceInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
return gridy;
}
private void buildAddressComboBoxModel() {
addressComboBoxModel.removeAllElements();
for (Address address : model.getAddresses()) {
addressComboBoxModel.addElement(address);
}
}
private void buildStateComboBoxModel() {
stateComboBoxModel.removeAllElements();
for (State state : model.getStates()) {
stateComboBoxModel.addElement(state);
}
}
private JPanel createButtonPanel() {
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(1, 3, 20, 0));
JButton addButton = new JButton("Add Address");
addButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
String message = checkFields();
if (message.equals("")) {
Address address = createAddress();
model.addAddress(address);
if (model.getAddresses().size() == 1) {
mainPanel.removeAll();
int gridy = 0;
gridy = createAddressComboBox(gridy);
gridy = createAddressControl(gridy);
} else {
clearFields();
addressComboBox.removeItemListener(listener);
buildAddressComboBoxModel();
addressComboBox.addItemListener(listener);
}
messageLabel.setForeground(Color.GREEN);
messageLabel.setText("Address \"" +
address.getName() + "\" saved");
} else {
messageLabel.setForeground(Color.RED);
messageLabel.setText(message);
}
}
});
addButton.setHorizontalAlignment(JButton.CENTER);
buttonPanel.add(addButton);
updateButton = new JButton("Change Address");
updateButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
String message = checkFields();
if (message.equals("")) {
Address changedAddress = createAddress();
updateReturnSenderAddresses(
currentAddress, changedAddress);
model.updateAddress(
currentAddress, changedAddress);
clearFields();
addressComboBox.removeItemListener(listener);
buildAddressComboBoxModel();
addressComboBox.addItemListener(listener);
messageLabel.setForeground(Color.GREEN);
messageLabel.setText("Address \"" +
currentAddress.getName() + "\" changed");
updateButton.setEnabled(false);
deleteButton.setEnabled(false);
} else {
messageLabel.setForeground(Color.RED);
messageLabel.setText(message);
}
}
});
updateButton.setEnabled(false);
updateButton.setHorizontalAlignment(JButton.CENTER);
buttonPanel.add(updateButton);
deleteButton = new JButton("Delete Address");
deleteButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
deleteReturnSenderAddresses(currentAddress);
model.removeAddress(currentAddress);
clearFields();
addressComboBox.removeItemListener(listener);
buildAddressComboBoxModel();
addressComboBox.addItemListener(listener);
messageLabel.setForeground(Color.GREEN);
messageLabel.setText("Address \"" +
currentAddress.getName() + "\" deleted");
updateButton.setEnabled(false);
deleteButton.setEnabled(false);
}
});
deleteButton.setEnabled(false);
deleteButton.setHorizontalAlignment(JButton.CENTER);
buttonPanel.add(deleteButton);
return buttonPanel;
}
private 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);
}
private String checkFields() {
String message = "";
State state = null;
try {
state = (State) stateComboBox.getSelectedItem();
} catch (ClassCastException e) {
message = "State abbreviation is invalid";
return message;
}
if (state == null) {
message = "State abbreviation is null";
return message;
}
String abbreviation = state.getAbbreviation();
boolean n = nameField.getText().trim().isEmpty();
boolean a = address1Field.getText().trim().isEmpty();
boolean c = cityField.getText().trim().isEmpty();
boolean s = abbreviation.trim().isEmpty();
boolean z = zip5Field.getText().trim().isEmpty();
if (n || a || c || s || z) {
message = "One or more required fields are empty";
return message;
}
// boolean x = stateField.getText().trim().length() > 2;
boolean g = isNumeric(zip5Field.getText().trim());
// if (x) {
// message = "State is more than 2 characters";
// return message;
// }
if (!g) {
message = "Zip 5 is not numeric";
return message;
}
if (zip4Field.getText().trim().isEmpty()) {
return message;
} else {
if (isNumeric(zip4Field.getText().trim())) {
return message;
} else {
message = "Zip 4 is not numeric";
return message;
}
}
}
private boolean isNumeric(String s) {
try {
Integer.valueOf(s);
return true;
} catch (NumberFormatException e) {
return false;
}
}
private Integer setZip(String s) {
return (s.isEmpty()) ? null : Integer.valueOf(s);
}
private Address createAddress() {
String abbreviation =
((State) stateComboBox.getSelectedItem())
.getAbbreviation();
return new Address(
nameField.getText().trim(),
address1Field.getText().trim(),
address2Field.getText().trim(),
cityField.getText().trim(),
abbreviation.toUpperCase(),
setZip(zip5Field.getText().trim()),
setZip(zip4Field.getText().trim())
);
}
private void clearFields() {
nameField.setText("");
address1Field.setText("");
address2Field.setText("");
cityField.setText("");
stateComboBox.setSelectedIndex(0);
zip5Field.setText("");
zip4Field.setText("");
}
private void setFields(Address address) {
nameField.setText(address.getName());
address1Field.setText(address.getAddressLine1());
address2Field.setText(address.getAddressLine2());
cityField.setText(address.getCity());
stateComboBox.setSelectedItem(
model.getStateByAbbreviation(address.getState()));
zip5Field.setText(String.format("%05d", address.getZip5()));
zip4Field.setText(displayZip4(address.getZip4()));
}
private String displayZip4(Integer value) {
return (value == null) ? "" : String.format("%04d", value);
}
private void updateReturnSenderAddresses(Address oldAddress,
Address newAddress) {
if (oldAddress.equals(model.getReturnAddress())) {
model.setReturnAddress(newAddress);
}
if (oldAddress.equals(model.getSenderAddress())) {
model.setSenderAddress(newAddress);
}
}
private void deleteReturnSenderAddresses(Address address) {
if (address.equals(model.getReturnAddress())) {
model.clearReturnAddress();
}
if (address.equals(model.getSenderAddress())) {
model.clearSenderAddress();
}
}
public void refresh() {
messageLabel.setText(" ");
}
public JPanel getMainPanel() {
return mainPanel;
}
public class AddressComboBoxItemListener implements ItemListener {
@Override
public void itemStateChanged(ItemEvent event) {
currentAddress = (Address)
addressComboBox.getSelectedItem();
setFields(currentAddress);
updateButton.setEnabled(true);
deleteButton.setEnabled(true);
}
}
}
我使用相同的addComponent方法将Swing组件添加到主JPanel。你可以看到我是如何处理JTextFields的。