我正在開發一個應用程式,它將通過 MyPanel 類中的按鈕和文本框從用戶那里獲取資訊。我想顯示用戶在 DisplayTable 面板中輸入的課程資訊。我希望每次按下 MyPanel 類中的添加課程按鈕時它都會更新。我嘗試從 MyPanel 類中呼叫 setLabelText 方法,實際功能應該是更新面板并在單擊按鈕時顯示傳遞串列中每個元素的文本,但仍然無法更新。你能告訴我每次按下 addCourseButton 時如何更新 DisplayPanel 的 infoLabel 文本嗎?
主類
public class Main {
//TODO
// PREVENT TYPE MISMATCH IN TEXT FIELDS
// DISPLAY A TABLE OF COURSE NAMES - COURSE CREDITS - COURSE NAME AND THE GPA
// CLEAN UP
public static void main(String[] args) {
new MyFrame();
}
}
類 MyFrame
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MyFrame extends JFrame{
MainPanel mainPanel;
MyFrame(){
mainPanel = new MainPanel();
this.add(mainPanel);
this.setTitle("GPA Calculator");
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(500,500);
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
}
}
類主面板
import javax.swing.*;
public class MainPanel extends JPanel {
DisplayPanel displayPanel = new DisplayPanel();
MyPanel myPanel = new MyPanel(displayPanel);
MainPanel() {
this.add(myPanel);
this.add(displayPanel);
}
}
類 MyPanel
import javax.swing.*;
import javax.swing.Timer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import java.util.List;
public class MyPanel extends JPanel implements ActionListener{
ArrayList<String> courseNames;
ArrayList<Integer> courseCredits;
ArrayList<Double> courseGrades;
Thread thread;
JLabel nameLabel;
JLabel creditLabel;
JLabel gradeLabel;
JTextField nameField;
JTextField creditField;
JTextField gradeField;
JButton calculateButton;
JButton addCourseButton;
JButton resetButton;
JLabel message;
DisplayPanel displayPanel;
double result = 0;
int tempInt = 0;
double tempDouble = 0;
MyPanel(DisplayPanel displayPanel) {
this.displayPanel = new DisplayPanel();
message = new JLabel();
message.setHorizontalAlignment(JLabel.CENTER);
message.setFont(new Font("Helvetica Neue", Font.PLAIN, 35));
message.setForeground(new Color(0xA1683A));
message.setAlignmentX(JLabel.CENTER_ALIGNMENT);
courseNames = new ArrayList();
courseCredits = new ArrayList();
courseGrades = new ArrayList();
nameLabel = new JLabel();
nameLabel.setHorizontalAlignment(JLabel.CENTER);
nameLabel.setText("Course Name");
nameLabel.setFont(new Font("Helvetica Neue", Font.PLAIN, 25));
nameLabel.setForeground(new Color(0xA1683A));
nameLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
nameField = new JTextField();
nameField.setPreferredSize(new Dimension(300,30));
nameField.setMaximumSize(nameField.getPreferredSize());
creditLabel = new JLabel();
creditLabel.setHorizontalAlignment(JLabel.CENTER);
creditLabel.setText("Course Credits(ECTS)");
creditLabel.setFont(new Font("Helvetica Neue", Font.PLAIN, 25));
creditLabel.setForeground(new Color(0xA1683A));
creditLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
creditField = new JTextField();
creditField.setPreferredSize(new Dimension(300,30));
creditField.setMaximumSize(creditField.getPreferredSize());
gradeLabel = new JLabel();
gradeLabel.setHorizontalAlignment(JLabel.CENTER);
gradeLabel.setText("Your Grade");
gradeLabel.setFont(new Font("Helvetica Neue", Font.PLAIN, 25));
gradeLabel.setForeground(new Color(0xA1683A));
gradeLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
gradeField = new JTextField();
gradeField.setPreferredSize(new Dimension(300,30));
gradeField.setMaximumSize(gradeField.getPreferredSize());
resetButton = new JButton("Reset");
resetButton.setAlignmentX(JLabel.CENTER_ALIGNMENT);
resetButton.addActionListener(this);
addCourseButton = new JButton("Add Course");
addCourseButton.setAlignmentX(JLabel.CENTER_ALIGNMENT);
addCourseButton.addActionListener(this);
calculateButton = new JButton("Calculate GPA");
calculateButton.setAlignmentX(JLabel.CENTER_ALIGNMENT);
calculateButton.addActionListener(this);
//spacing and adding the elements
this.add(Box.createRigidArea(new Dimension(0,20)));
this.add(nameLabel);
this.add(Box.createRigidArea(new Dimension(0,10)));
this.add(nameField);
this.add(Box.createRigidArea(new Dimension(0,20)));
this.add(creditLabel);
this.add(Box.createRigidArea(new Dimension(0,10)));
this.add(creditField);
this.add(Box.createRigidArea(new Dimension(0,20)));
this.add(gradeLabel);
this.add(Box.createRigidArea(new Dimension(0,10)));
this.add(gradeField);
this.add(Box.createRigidArea(new Dimension(0,20)));
this.add(addCourseButton);
this.add(Box.createRigidArea(new Dimension(0,5)));
this.add(calculateButton);
this.add(Box.createRigidArea(new Dimension(0,5)));
this.add(resetButton);
this.add(Box.createRigidArea(new Dimension(0,30)));
this.add(message);
this.setPreferredSize(new Dimension(500, 500));
this.setBackground(new Color(0xEED2CC));
this.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
}
//calculate the GPA
public double calculateGPA(){
for (Integer courseCredit : courseCredits) {
tempInt = courseCredit;
}
for(int i = 0; i<courseGrades.size();i ){
tempDouble = courseGrades.get(i) * courseCredits.get(i);
}
return tempDouble/tempInt;
}
@Override
public void actionPerformed(ActionEvent e) throws NumberFormatException {
if(e.getSource().equals(addCourseButton)){
//add items from the textFields to lists
String tempText = nameField.getText();
int tempCredit = Integer.parseInt(creditField.getText());
double tempGrade = Double.parseDouble(gradeField.getText());
courseNames.add(tempText);
courseCredits.add(tempCredit);
courseGrades.add(tempGrade);
//set textFields to empty
nameField.setText("");
creditField.setText("");
gradeField.setText("");
//display a message for 3 seconds
thread = new Thread();
thread.start();
message.setText("Course Added Successfully!");
Timer timer = new Timer(3000, a -> message.setText(null));
timer.setRepeats(false);
timer.start();
//add to table panel
displayPanel.setLabelText(courseNames,courseCredits,courseGrades);
//displayPanel.update();
}
//calculate the GPA, initialize the display panel
//to display the courses names-credits-results and the gpa
//as a table
if(e.getSource().equals(calculateButton)){
result = calculateGPA();
message.setText(result "");
}
//clear the lists,text fields and the message
//get rid of the table panel
if(e.getSource().equals(resetButton)){
courseNames.clear();
courseGrades.clear();
courseCredits.clear();
tempDouble = 0;
tempInt = 0;
displayPanel.removeAll();
displayPanel.repaint();
nameField.setText("");
creditField.setText("");
gradeField.setText("");
message.setText(null);
}
}
}
類 DisplayPanel
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
public class DisplayPanel extends JPanel {
JLabel infoLabel;
public DisplayPanel() {
this.setPreferredSize(new Dimension(500, 500));
this.setBackground(new Color(0xEED2CC));
this.setLayout(null);
infoLabel = new JLabel();
infoLabel.setHorizontalAlignment(JLabel.LEFT);
infoLabel.setFont(new Font("Helvetica Neue", Font.PLAIN, 35));
infoLabel.setForeground(new Color(0xA1683A));
infoLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
infoLabel.setBackground(Color.RED);
infoLabel.setOpaque(true);
this.add(infoLabel);
}
public void setLabelText(ArrayList<String> courseNames, ArrayList<Integer> courseCredits, ArrayList<Double> courseGrades) {
this.removeAll();
this.add(infoLabel);
this.repaint();
this.revalidate();
for (String name : courseNames) {
infoLabel.setText(name "\t" courseCredits.get(courseNames.indexOf(name)) "\t" courseGrades.get(courseNames.indexOf(name)));
}
infoLabel.setOpaque(true);
}
}
uj5u.com熱心網友回復:
您正在創建兩個 DisplayPanel,將一個添加到 GUI 并嘗試更改另一個未顯示的 DisplayPanel 的狀態。
class MainPanel extends JPanel {
DisplayPanel displayPanel = new DisplayPanel(); // *** HERE ***
MyPanel myPanel = new MyPanel(displayPanel);
MainPanel() {
this.add(myPanel);
this.add(displayPanel);
}
}
public class MyPanel extends JPanel implements ActionListener {
// ....
DisplayPanel displayPanel;
// ...
MyPanel(DisplayPanel displayPanel) {
this.displayPanel = new DisplayPanel(); // *** and HERE ***
// ...
}
// ...
}
而事實上,在 MainPanel 中,您正在嘗試將 DisplayPanel 物件添加到兩個不同的容器中,這在 Swing 中是不合法的,只有第二個 add 方法才會計數。
建議:
首先也是最重要的:創建一個類來保存您正在顯示的關鍵資訊。在下面的示例中,我將展示如何執行此操作,如何創建 CourseInfo 類來保存您最終將顯示的每一“行”資料。事實上,無論你決定如何顯示資料,我認為首先做這件事是你可以而且應該做的最重要的事情。
創建一個且只有一個組件,添加它并在需要時更改其狀態。
使用 JList 或更好的 JTable 來顯示資料。
避免使用空布局和 setBounds,而是使用布局管理器。在此處查看布局管理器教程:此處的布局管理器教程:
首先,一個類來保存存盤在 JTable 的每一行中的關鍵資訊,稱為 CourseInfo,它具有名稱 String、credits int 和 Grades 雙欄位:
public class CourseInfo { private String name; private int credits; private double grades; public CourseInfo(String name, int credits, double grades) { this.name = name; this.credits = credits; this.grades = grades; } public String getName() { return name; } public int getCredits() { return credits; } public double getGrades() { return grades; } }
接下來是一個 TableModel 類,它包含上述資訊的集合并允許在 JTable 中顯示它。我擴展了 DefaultTableModel,因為它預裝了內部偵聽器,這些偵聽器會在發生更改時通知外部物件(JTable 本身和添加到其中的任何偵聽器)。
The constructor calls the super's constructor that accepts the COLUMNS String array, the one that holds the names of the columns displayed in the JTable's header. The internal (super's) model holds a collection of CourseInfo objects, and the tricky part is displaying one CourseInfo object in 3 columns. This is done by making the column count 3, and by overriding
getValueAt(...)
so that it returns the correct CourseInfo field depending on the column parameterimport javax.swing.table.DefaultTableModel; @SuppressWarnings("serial") public class CourseTableModel extends DefaultTableModel { private static final String[] COLUMNS = { "Name", "Credits", "Grades" }; public CourseTableModel() { super(COLUMNS, 0); } public void addCourseInfo(CourseInfo courseInfo) { super.addRow(new CourseInfo[] { courseInfo }); } @Override public int getColumnCount() { return COLUMNS.length; } @Override public Object getValueAt(int row, int column) { CourseInfo courseInfo = (CourseInfo) super.getValueAt(row, 0); switch (column) { case 0: return courseInfo.getName(); case 1: return courseInfo.getCredits(); case 2: return courseInfo.getGrades(); default: throw new IllegalArgumentException("Unexpected value: " column); } } @Override public Class<?> getColumnClass(int columnIndex) { if (getRowCount() > 0) { return getValueAt(0, columnIndex).getClass(); } else { return super.getColumnClass(columnIndex); } } }
Next, the JPanel that displays the JTable, TablePanel. It also displays the GPA in a field. Note that there is not much to this class, that most of the program's logic is extracted out of it so that it focuses on the view or GUI aspect. The TableModel is passed into this via its constructor. It allows outside classes to set what is displayed in the gpaField via the
setGpa(...)
method:import java.awt.BorderLayout; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; @SuppressWarnings("serial") public class TablePanel extends JPanel { private JTable table; private JScrollPane scrollPane; private JTextField gpaField = new JTextField(10); public TablePanel(CourseTableModel tableModel) { int gap = 20; setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap)); setBackground(CoursesMainPanel.BACKGROUND); table = new JTable(tableModel); scrollPane = new JScrollPane(table); table.setOpaque(false); scrollPane.setOpaque(false); scrollPane.getViewport().setOpaque(false); JPanel gpaPanel = new JPanel(); gpaPanel.setOpaque(false); gpaPanel.add(new JLabel("GPA:")); gpaPanel.add(Box.createHorizontalStrut(10)); gpaPanel.add(gpaField); gpaField.setEditable(false); setLayout(new BorderLayout()); add(scrollPane); add(gpaPanel, BorderLayout.PAGE_END); } public void setGpa(String gpaText) { gpaField.setText(gpaText); } }
Next, the GetInfoPanel, a JPanel that gets the user's input. It has 3 JTextField's, JLabels, JButtons, and is organized via a GridBagLayout. It has a calcGpaButton, which is a relic from an earlier incarnation of this program, but which was disabled (and should be deleted probably), once I put the GPA calculation into a TableModelListener.
It too doesn't have much program logic, and outsources that to a control class, CoursesControl, that holds the code called by the button's ActionListeners. It has public methods, such as
public String getCourseName() {...
that allow the control class to extract information from this object when needed.import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.GridLayout; import java.awt.Insets; import java.awt.event.KeyEvent; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingConstants; @SuppressWarnings("serial") public class GetInfoPanel extends JPanel { private static final Font LABEL_FONT = new Font("Helvetica Neue", Font.PLAIN, 35); private static final int TXT_FLD_COLS = 15; private JTextField courseNameField = new JTextField(TXT_FLD_COLS); private JTextField courseCreditsField = new JTextField(TXT_FLD_COLS); private JTextField courseGradesField = new JTextField(TXT_FLD_COLS); private JButton addCourseButton = new JButton("Add Course"); private JButton calcGpaButton = new JButton("Calculate GPA"); // TODO: delete private JButton resetButton = new JButton("Reset"); private JButton exitButton = new JButton("Exit"); private int row = 0; private int insetGap = 2; private CoursesControl control; public GetInfoPanel() { int gap = 20; setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap)); setLayout(new GridBagLayout()); setBackground(CoursesMainPanel.BACKGROUND); addToPanel("Course Name", courseNameField); addToPanel("Course Credits", courseCreditsField); addToPanel("Your Grade", courseGradesField); addCourseButton.addActionListener(e -> addCourse()); calcGpaButton.addActionListener(e -> calcGpa()); resetButton.addActionListener(e -> reset()); exitButton.addActionListener(e -> exit()); addCourseButton.setMnemonic(KeyEvent.VK_A); calcGpaButton.setMnemonic(KeyEvent.VK_C); resetButton.setMnemonic(KeyEvent.VK_R); exitButton.setMnemonic(KeyEvent.VK_X); calcGpaButton.setEnabled(false); // Not needed JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 5, 0)); buttonPanel.setOpaque(false); buttonPanel.add(addCourseButton); buttonPanel.add(calcGpaButton); buttonPanel.add(resetButton); buttonPanel.add(exitButton); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = row; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.insets = new Insets(6 * insetGap, 3 * insetGap, 3 * insetGap, 3 * insetGap); add(buttonPanel, gbc); } public String getCourseName() { return courseNameField.getText(); } public String getCourseCredits() { return courseCreditsField.getText(); } public String getCourseGrades() { return courseGradesField.getText(); } public void clear() { courseNameField.setText(""); courseCreditsField.setText(""); courseGradesField.setText(""); courseNameField.requestFocusInWindow(); } public void setControl(CoursesControl control) { this.control = control; } private void addCourse() { if (control != null) { control.addCourse(); } clear(); } // TODO: delete as it is not really needed private void calcGpa() { if (control != null) { control.calcGpa(); } } private void reset() { if (control != null) { control.reset(); } clear(); } private void exit() { if (control != null) { control.exit(); } } private void addToPanel(String title, JTextField textField) { GridBagConstraints gbc = new GridBagConstraints(); gbc.anchor = GridBagConstraints.CENTER; gbc.gridx = 0; gbc.gridy = row; row ; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.insets = new Insets(3 * insetGap, 3 * insetGap, 0, 3 * insetGap); JLabel label = new JLabel(title); label.setFont(LABEL_FONT); label.setForeground(CoursesMainPanel.LABEL_FOREGROUND); label.setHorizontalAlignment(SwingConstants.CENTER); add(label, gbc); gbc.gridy = row; row ; gbc.insets.bottom = 3 * insetGap; textField.setFont(textField.getFont().deriveFont(20f)); add(textField, gbc); } }
Next the CoursesControl class, the one that holds most of the program's logic. This holds references to the view's GUI classes and methods that are called by the view's listeners. The
addCourse()
method extracts the text from the GetInfoPanel, it then validates that the numeric text is indeed numeric, and shows an error if not. If the data is good, it creates a new CourseInfo object with the data, and then adds a row to the table model by callingtableModel.addCourseInfo(courseInfo);
. It adds a TableModelListener to the table model and whenever the model changes, this class calculates and displays the GPA by callingtablePanel.setGpa
on the TablePanel instance:import java.awt.Window; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelListener; public class CoursesControl { private GetInfoPanel getInfoPanel; private CourseTableModel tableModel; private TablePanel tablePanel; public void setGetInfoPanel(GetInfoPanel getInfoPanel) { this.getInfoPanel = getInfoPanel; } public void setTableModel(CourseTableModel tableModel) { this.tableModel = tableModel; tableModel.addTableModelListener(new TableListener()); } public void setTablePanel(TablePanel tablePanel) { this.tablePanel = tablePanel; } public void addCourse() { if (getInfoPanel == null || tableModel == null) { return; } String courseName = getInfoPanel.getCourseName(); String courseCreditsTxt = getInfoPanel.getCourseCredits(); String courseGradesTxt = getInfoPanel.getCourseGrades(); int courseCredits = 0; try { courseCredits = Integer.parseInt(courseCreditsTxt); } catch (NumberFormatException e) { String message = "Course credits should be an integer"; String title = "Invalid Input"; int type = JOptionPane.ERROR_MESSAGE; JOptionPane.showMessageDialog(getInfoPanel, message, title, type); getInfoPanel.clear(); return; } double courseGrades = 0.0; try { courseGrades = Double.parseDouble(courseGradesTxt); } catch (NumberFormatException e) { String message = "Course grades should be an number"; String title = "Invalid Input"; int type = JOptionPane.ERROR_MESSAGE; JOptionPane.showMessageDialog(getInfoPanel, message, title, type); getInfoPanel.clear(); return; } CourseInfo courseInfo = new CourseInfo(courseName, courseCredits, courseGrades); tableModel.addCourseInfo(courseInfo); } private class TableListener implements TableModelListener { @Override public void tableChanged(TableModelEvent e) { if (tablePanel == null) { return; } int rows = tableModel.getRowCount(); if (rows == 0) { tablePanel.setGpa(""); } else { double sum = 0.0; int totalCredits = 0; for (int row = 0; row < rows; row ) { int credits = (int) tableModel.getValueAt(row, 1); double grade = (double) tableModel.getValueAt(row, 2); totalCredits = credits; sum = credits * grade; } double gpa = sum / totalCredits; tablePanel.setGpa(String.format("%.2f", gpa)); } } } public void reset() { if (tableModel != null) { tableModel.setRowCount(0); } } public void exit() { if (getInfoPanel != null) { Window window = SwingUtilities.getWindowAncestor(getInfoPanel); window.dispose(); } } // TODO: delete as it isn't needed public void calcGpa() { // This is not really needed, since the GPA is calculated in a table model listener } }
最后,一個主類將它們放在一起,創建一個 JFrame,并顯示它。這將創建此產品中的主要參與者,并通過將視圖物件傳遞給控制元件并將控制元件傳遞給需要它的視圖物件來將它們連接在一起:
import java.awt.Color; import java.awt.GridLayout; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; @SuppressWarnings("serial") public class CoursesMainPanel extends JPanel { public static final Color BACKGROUND = new Color(0xEED2CC); public static final Color LABEL_FOREGROUND = new Color(0xA1683A); private CoursesControl control = new CoursesControl(); private GetInfoPanel getInfoPanel = new GetInfoPanel(); private CourseTableModel tableModel = new CourseTableModel(); private TablePanel tablePanel = new TablePanel(tableModel); public CoursesMainPanel() { getInfoPanel.setControl(control); control.setGetInfoPanel(getInfoPanel); control.setTableModel(tableModel); control.setTablePanel(tablePanel); int gap = 2; setLayout(new GridLayout(1, 2, gap, gap)); add(getInfoPanel); add(tablePanel); } public static void main(String[] args) { SwingUtilities.invokeLater(() -> { JFrame frame = new JFrame("GUI"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new CoursesMainPanel()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); }); } }
uj5u.com熱心網友回復:
我將專注于解決您當前的問題,即
infoLabel
在課堂上顯示文本DisplayPanel
。你有三個問題。第一個是在 class 的建構式中
MyPanel
。MyPanel(DisplayPanel displayPanel) { this.displayPanel = new DisplayPanel();
您忽略了建構式引數并創建
DisplayPanel
. 因此displayPanel
class 的成員與MyPanel
您在 class 中創建的物件不同MainPanel
。所以你呼叫一個方法,DisplayPanel
這是不加入MainPanel
。您需要將該行更改為以下內容。MyPanel(DisplayPanel displayPanel) { this.displayPanel = displayPanel;
第二個問題是您在
DisplayPanel
. 當沒有布局管理器時,您需要顯式設定添加到JPanel
. 您沒有這樣做,因此JLabel
不會顯示您的。只需從的建構式中洗掉此行DisplayPanel
this.setLayout(null);
最后,在
setLabelText
class的 method 中DisplayPanel
,您只需要JLabel
通過 method 更改文本setText
。無需洗掉所有組件并再次添加它們。方法應該如下。public void setLabelText(ArrayList<String> courseNames, ArrayList<Integer> courseCredits, ArrayList<Double> courseGrades) { StringBuilder sb = new StringBuilder(); for (String name : courseNames) { sb.append(name "\t" courseCredits.get(courseNames.indexOf(name)) "\t" courseGrades.get(courseNames.indexOf(name))); } infoLabel.setText(sb.toString()); }
編輯
如果我的任務是制作這個應用程式,我會做如下的事情。
import java.awt.BorderLayout; import java.awt.EventQueue; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.text.ParseException; import javax.swing.JButton; import javax.swing.JFormattedTextField; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.table.DefaultTableModel; import javax.swing.text.MaskFormatter; public class GpaCalcs implements Runnable { private DefaultTableModel tableModel; private JFormattedTextField courseCreditsTextField; private JFormattedTextField gradeTextField; private JFrame frame; private JTable table; private JTextField courseNameTextField; public void run() { try { createAndDisplayGui(); } catch (Exception x) { throw new RuntimeException(x); } } private void addCourse(ActionEvent event) { Object[] row = new Object[3]; row[0] = courseNameTextField.getText(); row[1] = courseCreditsTextField.getValue(); row[2] = gradeTextField.getValue(); tableModel.addRow(row); } private void createAndDisplayGui() throws ParseException { frame = new JFrame("GPA Calculator"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(createMainPanel(), BorderLayout.CENTER); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); } private void createButtonsPanel(JPanel formPanel, GridBagConstraints gbc) { JPanel buttonsPanel = new JPanel(); JButton addCourseButton = new JButton("Add Course"); addCourseButton.addActionListener(this::addCourse); buttonsPanel.add(addCourseButton); JButton calcGpaButton = new JButton("Calculate GPA"); buttonsPanel.add(calcGpaButton); JButton resetButton = new JButton("Reset"); resetButton.addActionListener(this::reset); buttonsPanel.add(resetButton); gbc.gridwidth = 3; formPanel.add(buttonsPanel, gbc); } private JScrollPane createDisplayPanel() { String[] columns = new String[]{"Course", "Credits", "Grade"}; tableModel = new DefaultTableModel(columns, 0); table = new JTable(tableModel); JScrollPane scrollPane = new JScrollPane(table); return scrollPane; } private JPanel createFormPanel() throws ParseException { JPanel formPanel = new JPanel(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.anchor = GridBagConstraints.LINE_START; gbc.gridx = 0; gbc.gridy = 0; gbc.insets.bottom = 5; gbc.insets.left = 5; gbc.insets.right = 5; gbc.insets.top = 5; JLabel courseNameLabel = new JLabel("Course Name"); formPanel.add(courseNameLabel, gbc); gbc.gridx = 1; courseNameTextField = new JTextField(10); formPanel.add(courseNameTextField, gbc); gbc.gridx = 0; gbc.gridy = 1; JLabel courseCreditLabel = new JLabel("Course Credits (ECTS)"); formPanel.add(courseCreditLabel, gbc); gbc.gridx = 1; MaskFormatter formatter = new MaskFormatter("####"); // throws java.text.ParseException courseCreditsTextField = new JFormattedTextField(formatter); courseCreditsTextField.setColumns(10); formPanel.add(courseCreditsTextField, gbc); gbc.gridx = 0; gbc.gridy = 2; JLabel gradeLabel = new JLabel("Your Grade"); formPanel.add(gradeLabel, gbc); gbc.gridx = 1; formatter = new MaskFormatter("#.##"); gradeTextField = new JFormattedTextField(formatter); gradeTextField.setColumns(10); formPanel.add(gradeTextField, gbc); gbc.gridx = 0; gbc.gridy = 3; createButtonsPanel(formPanel, gbc); return formPanel; } private JPanel createMainPanel() throws ParseException { JPanel mainPanel = new JPanel(new GridLayout(0, 2)); mainPanel.add(createFormPanel()); mainPanel.add(createDisplayPanel()); return mainPanel; } private void reset(ActionEvent event) { courseNameTextField.setText(""); courseCreditsTextField.setText(""); gradeTextField.setText(""); } public static void main(String[] args) { EventQueue.invokeLater(new GpaCalcs()); } }
標籤:
上一篇:我用一個按鈕打開一個視窗。在那個視窗里面是另一個按鈕,它關閉剛剛打開的視窗并啟用第一個按鈕
下一篇:返回列表