布局不符合Swing中Java的预期
我是一名学生,有一个项目,应该有一个我已经实现的特定布局,除了由于一个错误或由于一些我不知道我做错了的事情而导致的一些间距问题,我已经确定了,所以我很难考虑以不同的方式来处理它。应该是这样的:
我的应用程序如下所示:
我正在关注Murach的Java编程,并试图仅使用本书范围内的任何东西来解决这个问题
我已经将组件添加到适当的面板中,并将它们添加到带有GridBagLayout的主面板中,以组织所有内容。由于某种原因,文本字段和组合框在单选按钮和复选框添加到面板后挂在右侧。我尝试过创建不同的面板来重新组织、更改布局设置、尝试其他布局、重写整个程序等等。几天前我向教练寻求帮助,但他们还没有回复我。我把Swing的章节读了好几遍,在谷歌上找不到合适的词了
编辑以添加所有代码:
学生调查。爪哇
package student.timothycdykes.studentsurvey;
public class StudentSurvey {
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(() -> {
new StudentSurveyFrame();
});
}
}
学生调查框架。爪哇
package student.timothycdykes.studentsurvey;
import java.awt.*;
import javax.swing.*;
public class StudentSurveyFrame extends JFrame {
public StudentSurveyFrame(){
try {
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException |
IllegalAccessException | UnsupportedLookAndFeelException e) {
System.err.println(e);
}
initComponents();
}
private void initComponents(){
setTitle("Student Survey");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationByPlatform(true);
// setLayout(new FlowLayout(FlowLayout.LEFT));
// Text Fields
Dimension dim = new Dimension(150,20);
JTextField firstNameTextField = new JTextField();
JTextField lastNameTextField = new JTextField();
firstNameTextField.setPreferredSize(dim);
firstNameTextField.setMinimumSize(dim);
lastNameTextField.setPreferredSize(dim);
lastNameTextField.setMinimumSize(dim);
// Combo Box
String[] countriesList = {"Select a country...",
"Albania",
"Bulgaria",
"Congo",
"Guernsey",
"Jamaica",
"Korea",
"Mozambique",
"Oman",
"Philippines",
"United States",
"Other"};
JComboBox countriesComboBox = new JComboBox(countriesList);
// Radio Buttons
ButtonGroup eyeColorButtonGroup = new ButtonGroup();
JRadioButton brownRadioButton = new JRadioButton("Brown");
JRadioButton greenRadioButton = new JRadioButton("Green");
JRadioButton blueRadioButton = new JRadioButton("Blue");
JRadioButton otherRadioButton = new JRadioButton("Other");
eyeColorButtonGroup.add(brownRadioButton);
eyeColorButtonGroup.add(greenRadioButton);
eyeColorButtonGroup.add(blueRadioButton);
eyeColorButtonGroup.add(otherRadioButton);
JPanel radioButtonPanel = new JPanel();
//radioButtonPanel.setBorder(BorderFactory.createEmptyBorder());
radioButtonPanel.add(brownRadioButton);
radioButtonPanel.add(greenRadioButton);
radioButtonPanel.add(blueRadioButton);
radioButtonPanel.add(otherRadioButton);
// Check Boxes
JCheckBox HTMLCheckBox = new JCheckBox("HTML");
JCheckBox SQLCheckBox = new JCheckBox("SQL");
JCheckBox javaCheckBox = new JCheckBox("Java");
JCheckBox 安卓CheckBox = new JCheckBox("Android");
JCheckBox pythonCheckBox = new JCheckBox("Python");
JPanel checkBoxPanel = new JPanel();
//checkBoxPanel.setBorder(BorderFactory.createEmptyBorder());
checkBoxPanel.add(HTMLCheckBox);
checkBoxPanel.add(SQLCheckBox);
checkBoxPanel.add(javaCheckBox);
checkBoxPanel.add(安卓CheckBox);
checkBoxPanel.add(pythonCheckBox);
// Buttons
JButton submitButton = new JButton("Submit");
submitButton.addActionListener(e -> {
// Create a message to append data to
String message = "Thanks for taking our survey!\n\n"
+ "Here's the data you entered:\n";
// Get the name
String firstName = firstNameTextField.getText();
String lastName = lastNameTextField.getText();
// Get the country
int countryIndex = countriesComboBox.getSelectedIndex();
String country = countriesList[countryIndex];
// Get the eye color
String eyeColor = "";
if (brownRadioButton.isSelected()) {
eyeColor = "Brown";
} else if (greenRadioButton.isSelected()) {
eyeColor = "Green";
} else if (blueRadioButton.isSelected()) {
eyeColor = "Blue";
} else if (otherRadioButton.isSelected()) {
eyeColor = "Other";
}
// Get the skills
String skills = "";
if (HTMLCheckBox.isSelected()) {
skills += "HTML";
}
if (SQLCheckBox.isSelected()) {
skills += ", SQL";
}
if (javaCheckBox.isSelected()) {
skills += ", Java";
}
if (安卓CheckBox.isSelected()) {
skills += ", Android";
}
if (pythonCheckBox.isSelected()) {
skills += ", Python";
}
// Validate, append to message, and show a dialog box
if (Validator.isEmpty(firstName, "First name") && Validator.isEmpty(lastName, "Last name")
&& Validator.isZeroIndex(countryIndex, "Country") && Validator.isEmpty(eyeColor, "Eye color")) {
message += "Name: " + firstName + " " + lastName + "\n";
message += "Country: " + country + "\n";
message += "Eye color: " + eyeColor + "\n";
message += "Skills: " + skills;
JOptionPane.showMessageDialog(this, message, "Message", JOptionPane.INFORMATION_MESSAGE);
}
});
JButton exitButton = new JButton("Exit");
exitButton.addActionListener(e -> {
System.exit(0);
});
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
buttonPanel.add(submitButton);
buttonPanel.add(exitButton);
// Grid Panel
JPanel northGridPanel = new JPanel();
northGridPanel.setLayout(new GridBagLayout());
northGridPanel.add(new JLabel("First Name:"), getConstraints(0,0));
northGridPanel.add(firstNameTextField, getConstraints(1,0));
northGridPanel.add(new JLabel("Last Name:"), getConstraints(0,1));
northGridPanel.add(lastNameTextField, getConstraints(1,1));
northGridPanel.add(new JLabel("Country:"), getConstraints(0,2));
northGridPanel.add(countriesComboBox, getConstraints(1,2));
northGridPanel.add(new JLabel("Eye color:"), getConstraints(0,3));
northGridPanel.add(radioButtonPanel, getConstraints(0,4));
northGridPanel.add(new JLabel("Programming skills:"), getConstraints(0,5));
northGridPanel.add(checkBoxPanel, getConstraints(0,6));
// Construct the frame
add(northGridPanel, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.SOUTH);
pack();
setVisible(true);
setLocationRelativeTo(null);
}
private GridBagConstraints getConstraints(int x, int y) {
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.LINE_START;
c.insets = new Insets(5, 5, 0, 5);
c.gridx = x;
c.gridy = y;
return c;
}
}
验证器。爪哇
package student.timothycdykes.studentsurvey;
import javax.swing.JOptionPane;
public class Validator {
private static void generateErrorDialog(String field) {
String message = "";
message += field + " is a required field."
+ "\nPlease complete this field before submitting.";
JOptionPane.showMessageDialog(null, message, "Error", JOptionPane.ERROR_MESSAGE);
}
public static boolean isEmpty(String string, String field) {
boolean isValid = true;
if (string.equals("")) {
isValid = false;
generateErrorDialog(field);
}
return isValid;
}
public static boolean isZeroIndex(int index, String field) {
boolean isValid = true;
if(index == 0) {
isValid = false;
generateErrorDialog(field);
}
return isValid;
}
}
我想补充一点,我知道代码没有遵循最佳实践。这本书中的一些材料已经过时,其中一些正是讲师所要求的
# 1 楼答案
我的怀疑是对的。以下是实施该建议的MRE。我还更改了其中一个文本字段的宽度,以演示不同列大小的效果
# 2 楼答案
你需要理解跨越单元的概念
网格中的每个单元格都是添加到列中的最大组件的大小
因此,单选按钮和复选框面板是第一列中最大的组件,因此其他组件显示在这些组件右侧的第二列中
因此,在为这两个面板创建约束时,需要指定每个面板占用两列的空间
阅读Swing教程中关于How to Use GridBagLayout的部分,特别是你需要看看
gridwidth
约束