Java 在每次单击时创建包含JTextField、JComboBox和JButton的新行
我正在使用JavaGUI创建一个GPA计算器。每次单击“添加课程”按钮时,程序都应为课程名称、学分和成绩添加一个文本字段 在这里,我使用HTML和Javascript制作了相同的程序 请参见屏幕截图: 我应该使用Java 在每次单击时创建包含JTextField、JComboBox和JButton的新行,java,swing,user-interface,awt,Java,Swing,User Interface,Awt,我正在使用JavaGUI创建一个GPA计算器。每次单击“添加课程”按钮时,程序都应为课程名称、学分和成绩添加一个文本字段 在这里,我使用HTML和Javascript制作了相同的程序 请参见屏幕截图: 我应该使用列表来存储文本字段吗?这是我在JavaGUI上的第一个项目 public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() {
列表来存储文本字段吗?这是我在JavaGUI上的第一个项目
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
CgpaCalculator window = new CgpaCalculator();
window.frmCgpaCalculator.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public CgpaCalculator() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frmCgpaCalculator = new JFrame();
frmCgpaCalculator.getContentPane().setFont(new Font("Tahoma", Font.PLAIN, 17));
frmCgpaCalculator.setTitle("CGPA Calculator");
frmCgpaCalculator.setBounds(100, 100, 540, 683);
frmCgpaCalculator.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmCgpaCalculator.getContentPane().setLayout(null);
textField = new JTextField();
textField.setBounds(12, 140, 126, 29);
frmCgpaCalculator.getContentPane().add(textField);
textField.setColumns(10);
textField_1 = new JTextField();
textField_1.setBounds(12, 175, 126, 29);
frmCgpaCalculator.getContentPane().add(textField_1);
textField_1.setColumns(10);
textField_2 = new JTextField();
textField_2.setBounds(12, 210, 126, 29);
frmCgpaCalculator.getContentPane().add(textField_2);
textField_2.setColumns(10);
textField_3 = new JTextField();
textField_3.setBounds(12, 245, 126, 29);
frmCgpaCalculator.getContentPane().add(textField_3);
textField_3.setColumns(10);
JLabel lblGrade = new JLabel("Course");
lblGrade.setFont(new Font("Tahoma", Font.PLAIN, 15));
lblGrade.setBounds(47, 99, 56, 16);
frmCgpaCalculator.getContentPane().add(lblGrade);
JComboBox comboBox = new JComboBox();
comboBox.setToolTipText("0");
comboBox.setModel(new DefaultComboBoxModel(new String[] {"3", "1", "2", "0", "1.5"}));
comboBox.setBounds(181, 140, 75, 29);
frmCgpaCalculator.getContentPane().add(comboBox);
JLabel lblCredits = new JLabel("Credits");
lblCredits.setFont(new Font("Tahoma", Font.PLAIN, 15));
lblCredits.setBounds(192, 99, 56, 16);
frmCgpaCalculator.getContentPane().add(lblCredits);
JComboBox comboBox_4 = new JComboBox();
comboBox_4.setModel(new DefaultComboBoxModel(new String[] {"A", "A-", "B+", "B", "B", "B-", "C+", "C", "D+", "D", "F"}));
comboBox_4.setBounds(297, 140, 70, 29);
frmCgpaCalculator.getContentPane().add(comboBox_4);
JComboBox comboBox_5 = new JComboBox();
comboBox_5.setModel(new DefaultComboBoxModel(new String[] {"A", "A-", "B+", "B", "B", "B-", "C+", "C", "D+", "D", "F"}));
comboBox_5.setBounds(297, 175, 70, 29);
frmCgpaCalculator.getContentPane().add(comboBox_5);
JComboBox comboBox_6 = new JComboBox();
comboBox_6.setModel(new DefaultComboBoxModel(new String[] {"A", "A-", "B+", "B", "B", "B-", "C+", "C", "D+", "D", "F"}));
comboBox_6.setBounds(297, 210, 70, 29);
frmCgpaCalculator.getContentPane().add(comboBox_6);
JComboBox comboBox_7 = new JComboBox();
comboBox_7.setModel(new DefaultComboBoxModel(new String[] {"A", "A-", "B+", "B", "B", "B-", "C+", "C", "D+", "D", "F"}));
comboBox_7.setBounds(297, 245, 70, 29);
frmCgpaCalculator.getContentPane().add(comboBox_7);
JComboBox comboBox_1 = new JComboBox();
comboBox_1.setModel(new DefaultComboBoxModel(new String[] {"3", "1", "2", "0", "1.5"}));
comboBox_1.setToolTipText("0");
comboBox_1.setBounds(181, 175, 75, 29);
frmCgpaCalculator.getContentPane().add(comboBox_1);
JComboBox comboBox_2 = new JComboBox();
comboBox_2.setModel(new DefaultComboBoxModel(new String[] {"3", "1", "2", "0", "1.5"}));
comboBox_2.setToolTipText("0");
comboBox_2.setBounds(181, 210, 75, 29);
frmCgpaCalculator.getContentPane().add(comboBox_2);
JComboBox comboBox_3 = new JComboBox();
comboBox_3.setModel(new DefaultComboBoxModel(new String[] {"3", "1", "2", "0", "1.5"}));
comboBox_3.setToolTipText("0");
comboBox_3.setBounds(181, 245, 75, 29);
frmCgpaCalculator.getContentPane().add(comboBox_3);
JLabel lblGrade_1 = new JLabel("Grade");
lblGrade_1.setFont(new Font("Tahoma", Font.PLAIN, 15));
lblGrade_1.setBounds(311, 99, 56, 16);
frmCgpaCalculator.getContentPane().add(lblGrade_1);
JButton btnNewButton = new JButton("Add Course");
btnNewButton.setFont(new Font("Tahoma", Font.PLAIN, 15));
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JOptionPane.showMessageDialog(frmCgpaCalculator.getComponent(0), "Hello World");
}
});
JLabel lblCgpa = new JLabel("CGPA:");
lblCgpa.setFont(new Font("Tahoma", Font.BOLD, 17));
lblCgpa.setBounds(386, 13, 56, 16);
frmCgpaCalculator.getContentPane().add(lblCgpa);
JLabel label = new JLabel("0.0");
label.setFont(new Font("Tahoma", Font.PLAIN, 17));
label.setBounds(454, 13, 56, 16);
frmCgpaCalculator.getContentPane().add(label);
btnNewButton.setBounds(12, 299, 124, 25);
frmCgpaCalculator.getContentPane().add(btnNewButton);
JButton btnCalculate = new JButton("Calculate");
btnCalculate.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
label.setText("3.2");
}
});
btnCalculate.setFont(new Font("Tahoma", Font.PLAIN, 15));
btnCalculate.setBounds(270, 300, 97, 25);
frmCgpaCalculator.getContentPane().add(btnCalculate);
}
更新:
如果不需要,我添加了一个按钮来删除一行。如何将其连接到数组列表索引
JButton btnX = new JButton("");
btnX.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
btnX.setIcon(new ImageIcon(CgpaCalculator.class.getResource("/com/sun/javafx/scene/control/skin/modena/dialog-error.png")));
btnX.setBackground(Color.RED);
btnX.setForeground(Color.WHITE);
btnX.setBounds(428, rowY, 30, 30);
frmCgpaCalculator.getContentPane().add(btnX);
我将创建一个对象来保存每行的3个元素,称为CourseRow
。并将这些CourseRow
对象存储在列表中
下面是以这种方式重写的代码:
public class Test {
public static void main(String[] args) {
CgpaCalculator window = new CgpaCalculator();
window.getFrmCgpaCalculator().setVisible(true);
}
}
class CgpaCalculator {
private JFrame frmCgpaCalculator;
private JPanel coursesPanel;
private JScrollPane scrollPane;
// Define some constants
private int ROWS_Y_OFFEST = 0;
private int ROW_HEIGHT = 35;
private String[] credits = new String[] {"3", "1", "2", "0", "1.5"};
private String[] grades = new String[] {"A", "A-", "B+", "B", "B", "B-", "C+", "C", "D+", "D", "F"};
// This list holds all the row elements
private List<CourseRow> courseRows = new ArrayList<>();
// These 2 need to be class variable because we update them in the refresh method
private JButton btnNewButton, btnCalculate;
public CgpaCalculator() {
initializeElements();
refresh();
}
private void initializeElements() {
frmCgpaCalculator = new JFrame();
frmCgpaCalculator.getContentPane().setFont(new Font("Tahoma", Font.PLAIN, 17));
frmCgpaCalculator.setTitle("CGPA Calculator");
frmCgpaCalculator.setBounds(100, 100, 540, 683);
frmCgpaCalculator.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frmCgpaCalculator.getContentPane().setLayout(null);
// CGPA RESULT
JLabel lblCgpa = new JLabel("CGPA:");
lblCgpa.setFont(new Font("Tahoma", Font.BOLD, 17));
lblCgpa.setBounds(386, 13, 56, 16);
frmCgpaCalculator.getContentPane().add(lblCgpa);
JLabel label = new JLabel("0.0");
label.setFont(new Font("Tahoma", Font.PLAIN, 17));
label.setBounds(454, 13, 56, 16);
frmCgpaCalculator.getContentPane().add(label);
// HEADERS
JLabel lblCourse = new JLabel("Course");
lblCourse.setFont(new Font("Tahoma", Font.PLAIN, 15));
lblCourse.setBounds(47, 99, 56, 16);
frmCgpaCalculator.getContentPane().add(lblCourse);
JLabel lblCredits = new JLabel("Credits");
lblCredits.setFont(new Font("Tahoma", Font.PLAIN, 15));
lblCredits.setBounds(192, 99, 56, 16);
frmCgpaCalculator.getContentPane().add(lblCredits);
JLabel lblGrade = new JLabel("Grade");
lblGrade.setFont(new Font("Tahoma", Font.PLAIN, 15));
lblGrade.setBounds(311, 99, 56, 16);
frmCgpaCalculator.getContentPane().add(lblGrade);
// Courses panel and scroll pane
coursesPanel = new JPanel();
coursesPanel.setLayout(null);
scrollPane = new JScrollPane(coursesPanel);
scrollPane.setBounds(40, 150, 480, 300);
scrollPane.setPreferredSize(new Dimension(500, 300));
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
frmCgpaCalculator.getContentPane().add(scrollPane);
// BUTTONS
btnNewButton = new JButton("Add Course");
btnNewButton.setFont(new Font("Tahoma", Font.PLAIN, 15));
btnNewButton.setBounds(12, 500, 124, 25);
btnNewButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
addCourseRow();
}
}
);
frmCgpaCalculator.getContentPane().add(btnNewButton);
btnCalculate = new JButton("Calculate");
btnCalculate.setFont(new Font("Tahoma", Font.PLAIN, 15));
btnCalculate.setBounds(270, 500, 97, 25);
btnCalculate.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
label.setText("3.2");
}
});
frmCgpaCalculator.getContentPane().add(btnCalculate);
// Add 3 default rows
addCourseRow();
addCourseRow();
addCourseRow();
}
// This method refreshes the view.
// It takes the list of course rows and reposition them depending on their index in the list
// This enabled to easily handle deleting rows in the middle
private void refresh() {
// Reposition all course rows
int rowY = ROWS_Y_OFFEST;
CourseRow courseRow;
for(int rowIndex=0; rowIndex<courseRows.size(); rowIndex++) {
courseRow = courseRows.get(rowIndex);
rowY = ROWS_Y_OFFEST + rowIndex * ROW_HEIGHT;
courseRow.getNameJTextField().setBounds(12, rowY, 126, 29);
courseRow.getCreditsJComboBox().setBounds(181, rowY, 75, 29);
courseRow.getGradeJComboBox().setBounds(297, rowY, 70, 29);
courseRow.getDeleteJButton().setBounds(428, rowY, 30, 30);
}
// resize the course panel so the scroll pane knows if it needs to add the scroll bar
// you need to use the setPreferredSize method
coursesPanel.setPreferredSize(new Dimension(450, rowY + ROW_HEIGHT));
// repaint the scroll pane
scrollPane.invalidate();
scrollPane.validate();
scrollPane.repaint();
}
private void addCourseRow() {
// Calculate the Y coordinate of the row
long rowId = System.currentTimeMillis();
// Create the 3 elements
JTextField nameJTextField = new JTextField();
nameJTextField.setColumns(10);
coursesPanel.add(nameJTextField);
JComboBox creditsJComboBox = new JComboBox();
creditsJComboBox.setToolTipText("0");
creditsJComboBox.setModel(new DefaultComboBoxModel(credits));
coursesPanel.add(creditsJComboBox);
JComboBox gradeJComboBox = new JComboBox();
gradeJComboBox.setModel(new DefaultComboBoxModel(grades));
coursesPanel.add(gradeJComboBox);
JButton btnX = new JButton("");
btnX.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
removeCourse(rowId);
}
});
btnX.setIcon(new ImageIcon(CgpaCalculator.class.getResource("/com/sun/javafx/scene/control/skin/modena/dialog-error.png")));
btnX.setBackground(Color.RED);
btnX.setForeground(Color.WHITE);
coursesPanel.add(btnX);
// Add the row to the list
CourseRow courseRow = new CourseRow();
courseRow.setId(rowId);
courseRow.setNameJTextField(nameJTextField);
courseRow.setCreditsJComboBox(creditsJComboBox);
courseRow.setGradeJComboBox(gradeJComboBox);
courseRow.setDeleteJButton(btnX);
courseRows.add(courseRow);
refresh();
}
private void removeCourse(long rowId) {
// find the course row by id
Optional<CourseRow> rowOption = courseRows.stream().filter(r -> r.getId() == rowId).findFirst();
if(rowOption.isPresent()) {
CourseRow row = rowOption.get();
// remove elements of this row from the JFrame
coursesPanel.remove(row.getNameJTextField());
coursesPanel.remove(row.getCreditsJComboBox());
coursesPanel.remove(row.getGradeJComboBox());
coursesPanel.remove(row.getDeleteJButton());
// remove row from the list
courseRows.remove(row);
} else {
System.out.println("Could not find row with id "+rowId);
}
refresh();
}
public JFrame getFrmCgpaCalculator() {
return frmCgpaCalculator;
}
}
class CourseRow {
private long id;
private JTextField nameJTextField;
private JComboBox creditsJComboBox;
private JComboBox gradeJComboBox;
private JButton deleteJButton;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public JTextField getNameJTextField() {
return nameJTextField;
}
public void setNameJTextField(JTextField nameJTextField) {
this.nameJTextField = nameJTextField;
}
public JComboBox getCreditsJComboBox() {
return creditsJComboBox;
}
public void setCreditsJComboBox(JComboBox creditsJComboBox) {
this.creditsJComboBox = creditsJComboBox;
}
public JComboBox getGradeJComboBox() {
return gradeJComboBox;
}
public void setGradeJComboBox(JComboBox gradeJComboBox) {
this.gradeJComboBox = gradeJComboBox;
}
public JButton getDeleteJButton() {
return deleteJButton;
}
public void setDeleteJButton(JButton deleteJButton) {
this.deleteJButton = deleteJButton;
}
}
公共类测试{
公共静态void main(字符串[]args){
CgpaCalculator窗口=新的CgpaCalculator();
window.getfrmgcpacalculator().setVisible(true);
}
}
类CGP计算器{
专用JFrame-frmgcpaccalculator;
私人JPanel coursesPanel;
私有JScrollPane滚动窗格;
//定义一些常量
private int ROWS_Y_OFFEST=0;
私人int ROW_高度=35;
私有字符串[]信用=新字符串[]{“3”、“1”、“2”、“0”、“1.5”};
私有字符串[]等级=新字符串[]{“A”、“A-”、“B+”、“B”、“B-”、“C+”、“C”、“D+”、“D”、“F”};
//此列表包含所有行元素
私有列表courseRows=newArrayList();
//这2个变量必须是类变量,因为我们在refresh方法中更新它们
私有JButton btnNewButton,btnCalculate;
公共CgpaCalculator(){
初始化元素();
刷新();
}
私有无效初始化元素(){
frmgcpacalculator=newjframe();
frmgcpaccalculator.getContentPane().setFont(新字体(“Tahoma”,Font.PLAIN,17));
frmgcpaccalculator.setTitle(“CGPA计算器”);
frmgcpaccalculator.setBounds(100100540683);
FRMCGPaculator.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frmgcpaccalculator.getContentPane().setLayout(null);
//CGPA结果
JLabel lblCgpa=新JLabel(“CGPA:”);
lblCgpa.setFont(新字体(“Tahoma”,Font.BOLD,17));
lblCgpa.立根(386,13,56,16);
frmgcpaccalculator.getContentPane().add(lblCgpa);
JLabel标签=新的JLabel(“0.0”);
label.setFont(新字体(“Tahoma”,Font.PLAIN,17));
标签.立根(454,13,56,16);
frmgcpaccalculator.getContentPane().add(标签);
//标题
JLabel lblCourse=新JLabel(“课程”);
lblCourse.setFont(新字体(“Tahoma”,Font.PLAIN,15));
LBL课程挫折(47,99,56,16);
frmgcpaccalculator.getContentPane().add(lblCourse);
JLabel LBL信用=新JLabel(“信用”);
lblCredits.setFont(新字体(“Tahoma”,Font.PLAIN,15));
LBL信用卡退步(192,99,56,16);
frmgcpaccalculator.getContentPane().add(lblCredits);
JLabel lblGrade=新JLabel(“等级”);
lblGrade.setFont(新字体(“Tahoma”,Font.PLAIN,15));
lblGrade.挫折(311,99,56,16);
frmgcpaccalculator.getContentPane().add(lblGrade);
//课程面板和滚动窗格
coursesPanel=新的JPanel();
coursesPanel.setLayout(空);
滚动窗格=新的JScrollPane(coursesPanel);
滚动窗格.立根(40150480300);
scrollPane.setPreferredSize(新维度(500300));
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL\u SCROLLBAR\u ALWAYS);
frmgcpaccalculator.getContentPane().add(滚动窗格);
//钮扣
btnNewButton=新JButton(“添加课程”);
setFont(新字体(“Tahoma”,Font.PLAIN,15));
btnNewButton.setBounds(12500124,25);
addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件arg0){
addCourseRow();
}
}
);
frmgcpaccalculator.getContentPane().add(btnNewButton);
btnCalculate=新的JButton(“计算”);
setFont(新字体(“Tahoma”,Font.PLAIN,15));
计算立根数(270,500,97,25);
btnCalculate.addActionListener(新的ActionListener(){
@凌驾
已执行的公共无效操作(操作事件arg0){
label.setText(“3.2”);
}
});
frmgcpaccalculator.getContentPane().add(btnCalculate);
//添加3个默认行
addCourseRow();
addCourseRow();
addCourseRow();
}
//此方法刷新视图。
//它获取课程行列表,并根据它们在列表中的索引重新定位它们
//这使得能够轻松地处理中间行的删除。
私有无效刷新(){
//重新定位所有课程行
int rowY=行数;
CourseRow CourseRow;
对于(int rowIndex=0;rowIndex r.getId()==rowId).findFirst();
if(rowOption.isPresent()){
CourseRow行=rowOption.get();
//从JFrame中删除此行的元素
移除(row.getNameJTextField());
coursePanel.remove(row.getCreditsJComboBox());
coursePanel.remove(row.getGradeJComboBox());
coursePanel.remove(row.getDeleteJButton());
//从列表中删除行
courseRows.移除(行);
}否则{
System.out.println(“找不到id为“+rowId”的行);
}
刷新();
}
公共JFrame getfrmgcpacalculator(){
返回FRMCG计算器;
}
}
班级课程{
私人长id;
私有JTextField名称JTextField;
私人JComboBox creditsJComboBox;
私人JCOMBOX等级JCOMBOX;
私有JButton deleteJButton;
公共长getId(){
返回id;
}
公共空间