Java Swing航班座位系统Chart类按钮无响应问题排查
已实现功能清单
- 座位分配交互:点击座位按钮后依次弹窗收集乘客名、姓,校验通过后弹出「[姓名]已分配至[座位号]」的提示,对应按钮变红、文本改为X标记已占用,乘客信息存入
ArrayList<Seat>集合 - 航班舱单管理:已分配乘客信息可写入本地文件,支持打开舱单页面按姓名或座位号排序展示
- 候补名单管理:支持用户自主增删候补名单人员
问题现象
运行主类Chart时界面所有按钮点击无响应,且无任何错误提示。
核心问题定位
源码存在3个直接导致按钮失效、运行异常的根因:
initComponents()方法代码残缺,未完成按钮事件绑定
NetBeans自动生成的初始化代码块被截断:@SuppressWarnings("unchecked")注解下直接跟了pack(); },完全缺失所有UI组件初始化、按钮点击监听器绑定的逻辑。你写的buttonActionPerformedCommon、exitBtnActionPerformed、manifestActionPerformed等事件处理方法,根本没有被注册到对应按钮的ActionListener上,点击按钮自然不会触发任何逻辑。这是NetBeans GUI编辑器生成代码被误删/粘贴不全导致的,回到GUI设计界面重新保存生成代码即可恢复基础的监听器绑定结构。
allSeats集合未初始化,空指针异常被Swing事件线程吞掉
代码只声明了ArrayList<Seat> allSeats;,没有在构造方法里赋值,第一次调用addSeat()执行allSeats.add(seat)时会直接抛NullPointerException。Swing事件调度线程默认捕获异常后不会在控制台打印明显报错,就会表现为点击无响应。
修复方式:在Chart构造方法中增加初始化逻辑:public Chart() { allSeats = new ArrayList<>(); nameSave = new File("nameList.txt"); initComponents(); checkFile(); }座位点击逻辑存在死循环,直接卡死UI线程
buttonActionPerformedCommon方法中写了while (btn.isSelected())循环:普通JButton点击后isSelected()默认不会自动变为false,这个循环会一直执行反复弹确认框,点选NO也不会退出循环,直接把UI线程卡死。
修复方式:直接删掉这段无意义的while循环,座位分配完成后给按钮加禁用逻辑即可,不需要循环判断选中状态。
其他潜在bug提示
- 输入名校验逻辑存在空指针风险:用户点弹窗取消按钮、或者输入空字符串时,
firstName/lastName会是null,直接调用isEmpty()会抛异常,需要先判空:if (firstName == null || firstName.trim().isEmpty()) { return; } - 写文件逻辑每次打开舱单都会重复追加全量乘客数据,会导致
nameList.txt里重复记录越来越多,建议写文件前先清空原有内容,不要用追加模式。 - 打开新窗口不要用废弃的
show()方法,改用setVisible(true),跨JDK版本兼容性更好。
附Chart类完整源码
/* * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license * Click nbfs://nbhost/SystemFileSystem/Templates/GUIForms/JFrame.java to edit this template */ package air.canada; import java.io.File; import javax.swing.JOptionPane; import java.awt.Color; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Locale; /** * * @author sprince */ public class Chart extends javax.swing.JFrame { //Added Generic Arraylist of Type Seat ArrayList<Seat> allSeats; File nameSave; /** * Creates new form Chart */ public Chart() { initComponents(); } //Added Function to write passengers list in file public void writeNamesInFile(ArrayList<Seat> allSeats) { nameSave = new File("nameList.txt"); try { FileWriter fw = new FileWriter(nameSave, true); String strOutput = ""; for (int i = 0; i < allSeats.size(); i++) { strOutput = strOutput + allSeats.get(i).getFirstName() + "\t" + allSeats.get(i).getLastName() + "\t" + allSeats.get(i).getSeat() + "\n"; } fw.write(strOutput); fw.close(); } catch (IOException e) { e.printStackTrace(); } } //add details in arraylist public void addSeat(String firstName, String lastName, String seatNameNumber) { //Create seat object Seat seat = new Seat(); //set firstname lastname and seat seat.setFirstName(firstName); seat.setLastName(lastName); seat.setSeat(seatNameNumber.toUpperCase(Locale.ROOT)); //add seat to arraylist allSeats.add(seat); } //Get all Seats that will return arraylist public ArrayList<Seat> getAllSeats() { return allSeats; } public void setAisle(javax.swing.JLabel aisleLabel, String aisleNo) { aisleLabel.setFont(new java.awt.Font("Arial", 0, 18)); aisleLabel.setForeground(new java.awt.Color(255, 0, 0)); aisleLabel.setText(aisleNo); } public void setButtons(javax.swing.JButton jButton, String btnText) { jButton.setFont(new java.awt.Font("Arial", 0, 18)); // NOI18N jButton.setText(btnText); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") pack(); }// </editor-fold> private void buttonActionPerformedCommon(javax.swing.JButton btn, java.awt.event.ActionEvent evt, String seat) { //get first name String firstName = javax.swing.JOptionPane.showInputDialog(null, "Please enter your first name.", "Information Required", JOptionPane.INFORMATION_MESSAGE); // if input is empty, exit if (firstName.isEmpty()) { } else { System.out.println(firstName); //get last name String lastName = javax.swing.JOptionPane.showInputDialog(null, "Please enter your last name.", "Information Required", JOptionPane.INFORMATION_MESSAGE); // if input is empty, exit if (lastName.isEmpty()) { } else { System.out.println(lastName); //output, ___ has been assigned to seat ____ JOptionPane.showMessageDialog(rootPane, firstName + " " + lastName + " has been assigned to seat " + seat + "!", "YAY", JOptionPane.INFORMATION_MESSAGE); //change colour of button btn.setBackground(Color.red); //keep text black btn.setForeground(Color.black); //change text to X btn.setText("X"); //ADDED addSeat(firstName, lastName, seat); while (btn.isSelected()) { int result = JOptionPane.showConfirmDialog(null, "Would you like to remove " + firstName + " " + lastName + " form " + seat + "? ", "Replace?", JOptionPane.YES_NO_OPTION); if (result == JOptionPane.YES_OPTION) { System.exit(0); } } } } } private void exitBtnActionPerformed(java.awt.event.ActionEvent evt) { //exit program int result = JOptionPane.showConfirmDialog(null,"Would you like to exit?", "Exit?", JOptionPane.YES_NO_OPTION); if (result == JOptionPane.YES_OPTION) { System.exit(0);} } private void manifestActionPerformed(java.awt.event.ActionEvent evt) { //Open Manifest //p2 = plan 2 Manifest p2 = new Manifest(allSeats); //get names writeNamesInFile(allSeats); //display frame p2.show(); } private void waitlistActionPerformed(java.awt.event.ActionEvent evt) { //Open Manifest //p3 = plan 3 Waitlist p3 = new Waitlist(); //display frame p3.show(); } public void checkFile() { try { if (nameSave.exists() == false) { nameSave.createNewFile(); } } catch (IOException e) { JOptionPane.showMessageDialog(rootPane, "File not found"); e.printStackTrace(); } } /** * @param args the command line arguments */ public static void main(String args[]) { /* Set the Nimbus look and feel */ //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(Chart.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(Chart.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(Chart.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(Chart.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } //</editor-fold> /* Create and display the form */ java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new Chart().setVisible(true); } }); } // Variables declaration - do not modify private javax.swing.JButton a1; private javax.swing.JButton a10; private javax.swing.JButton a2; private javax.swing.JButton a3; private javax.swing.JButton a4; private javax.swing.JButton a5; private javax.swing.JButton a6; private javax.swing.JButton a7; private javax.swing.JButton a8; private javax.swing.JButton a9; private javax.swing.JLabel aisle1; private javax.swing.JLabel aisle10; private javax.swing.JLabel aisle2; private javax.swing.JLabel aisle3; private javax.swing.JLabel aisle4; private javax.swing.JLabel aisle5; private javax.swing.JLabel aisle6; private javax.swing.JLabel aisle7; private javax.swing.JLabel aisle8; private javax.swing.JLabel aisle9; private javax.swing.JButton b1; private javax.swing.JButton b10; private javax.swing.JButton b2; private javax.swing.JButton b3; private javax.swing.JButton b4; private javax.swing.JButton b5; private javax.swing.JButton b6; private javax.swing.JButton b7; private javax.swing.JButton b8; private javax.swing.JButton b9; private javax.swing.JButton c1; private javax.swing.JButton c10; private javax.swing.JButton c2; private javax.swing.JButton c3; private javax.swing.JButton c4; private javax.swing.JButton c5; private javax.swing.JButton c6; private javax.swing.JButton c7; private javax.swing.JButton c8; private javax.swing.JButton c9; private javax.swing.JLabel chartLbl; private javax.swing.JButton d1; private javax.swing.JButton d10; private javax.swing.JButton d2; private javax.swing.JButton d3; private javax.swing.JButton d4; private javax.swing.JButton d5; private javax.swing.JButton d6; private javax.swing.JButton d7; private javax.swing.JButton d8; private javax.swing.JButton d9; private javax.swing.JButton e1; private javax.swing.JButton e10; private javax.swing.JButton e2; private javax.swing.JButton e3; private javax.swing.JButton e4; private javax.swing.JButton e5; private javax.swing.JButton e6; private javax.swing.JButton e7; private javax.swing.JButton e8; private javax.swing.JButton e9; private javax.swing.JButton exitBtn; private javax.swing.JButton f1; private javax.swing.JButton f10; private javax.swing.JButton f2; private javax.swing.JButton f3; private javax.swing.JButton f4; private javax.swing.JButton f5; private javax.swing.JButton f6; private javax.swing.JButton f7; private javax.swing.JButton f8; private javax.swing.JButton f9; private javax.swing.JButton g1; private javax.swing.JButton g10; private javax.swing.JButton g2; private javax.swing.JButton g3; private javax.swing.JButton g4; private javax.swing.JButton g5; private javax.swing.JButton g6; private javax.swing.JButton g7; private javax.swing.JButton g8; private javax.swing.JButton g9; private javax.swing.JButton h1; private javax.swing.JButton h10; private javax.swing.JButton h2; private javax.swing.JButton h3; private javax.swing.JButton h4; private javax.swing.JButton h5; private javax.swing.JButton h6; private javax.swing.JButton h7; private javax.swing.JButton h8; private javax.swing.JButton h9; private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItem1; private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItem2; private javax.swing.JMenu jMenu1; private javax.swing.JMenu jMenu10; private javax.swing.JMenu jMenu11; private javax.swing.JMenu jMenu12; private javax.swing.JMenu jMenu2; private javax.swing.JMenu jMenu3; private javax.swing.JMenu jMenu4; private javax.swing.JMenu jMenu5; private javax.swing.JMenu jMenu6; private javax.swing.JMenu jMenu7; private javax.swing.JMenu jMenu8; private javax.swing.JMenu jMenu9; private javax.swing.JMenuBar jMenuBar1; private javax.swing.JMenuBar jMenuBar2; private javax.swing.JMenuBar jMenuBar3; private javax.swing.JMenuBar jMenuBar4; private javax.swing.JMenuBar jMenuBar5; private javax.swing.JMenuBar jMenuBar6; private javax.swing.JButton manifest; private javax.swing.JButton waitlist; // End of variables declaration }
内容的提问来源于stack exchange,提问作者Mitzy 33

