Java Swing注册页与主页窗口连接问题求助
问题
开发适配特殊发票机的发票系统,采用JavaFX结合Swing技术。已完成连接SQLite数据库的注册页面(Invoice1.java),关联注册页与主页(Home.java)时出现异常:
- 点击注册页「创建账户」按钮,弹出「账户已创建」提示框;点击提示框「OK」后,注册页面板被隐藏,但弹出的主页窗口为空白。
- 要求手动编码实现页面跳转,禁止使用JForms(项目将其视为低代码)。
现有代码
Invoice1.java
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package invoice1; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.sql.*; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; /** * * @author kate3 */ public class Invoice1 extends Home { private static JLabel nameLabel; private static JTextField nameText; private static JLabel passwordLabel; private static JTextField passwordText; private static JButton button; /** * @param args the command line arguments */ public static void main(String[] args) { /*Creating the signup form, part of code used from: https://www.youtube.com/watch?v=iE8tZ0hn2Ws) */ JPanel panel = new JPanel(); JFrame frame = new JFrame(); frame.setSize(350, 200); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(panel); panel.setLayout(null); nameLabel = new JLabel("Business Name"); nameLabel.setBounds(10, 20, 80, 25); panel.add(nameLabel); nameText = new JTextField(40); nameText.setBounds(100, 20, 165, 25); panel.add(nameText); passwordLabel = new JLabel ("Create Password"); passwordLabel.setBounds (10, 50, 80, 25); panel.add(passwordLabel); passwordText = new JTextField(20); passwordText.setBounds(100, 50, 165, 25); panel.add(passwordText); button = new JButton("Create Account"); button.setBounds(130, 110, 80, 25); frame.setVisible(true); button.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e){ String name = nameText.getText(); String password = passwordText.getText(); addToDB(name, password); JOptionPane.showMessageDialog(frame, "Account Created!"); panel.setVisible(false); Home.setVisible(true); } }); panel.add(button); frame.setVisible(true); } /* keeping in file in case needed in future public void buttonPerformed(ActionEvent e) { String name = nameText.getText(); String password = passwordText.getText(); if(name.equals("kate") && password.equals("password")){ successful.setText("Login successful!"); } }*/ //adding data inputted to database public static void addToDB ( String un, String pass){ Connection dbCon = null; String strUrl = "jdbc:sqlite:testDB.db"; try{ dbCon = DriverManager.getConnection(strUrl, "root", "root"); System.out.println("Connected"); Statement st = dbCon.createStatement(); PreparedStatement stmt = dbCon.prepareStatement("Select * From loginDetails"); st.executeUpdate("insert into loginDetails (username, password)" + " values ('" + un + "' , '" + pass + "')"); ResultSet rs = stmt.executeQuery(); while(rs.next()){ System.out.println(rs.getString(1)); System.out.println(rs.getString(2)); } }catch(SQLException e){ } } /* @Override public void actionPerformed(ActionEvent e) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } */ }
Home.java
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package invoice1; import java.awt.PopupMenu; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; /** * * @author kate3 */ public class Home { private static JLabel homeLabel ; private static JButton invoiceButton; private static JButton invoiceHistory; private static JButton statementButton; private static JButton statementHistory; private static JButton productButton; private static JButton customerButton; public static void main(String[] args) { JPanel home = new JPanel(); //linking Invoice1 JFrame Home.getInvoice1(); // frame.setSize(350, 200); Home.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); home.setLayout(null); homeLabel = new JLabel("HOME"); homeLabel.setBounds(100, 20, 80, 25); home.add(homeLabel); invoiceButton = new JButton("Create Invoice"); invoiceButton.setBounds(100, 50, 80, 25); home.add(invoiceButton); statementButton = new JButton("Create Statement"); statementButton.setBounds(100, 80, 80, 25); home.add(statementButton); invoiceHistory = new JButton("Invoice History"); invoiceHistory.setBounds(100, 80, 80, 25); home.add(invoiceHistory); statementHistory = new JButton("Statement History"); statementHistory.setBounds(100, 140, 80, 25); home.add(statementHistory); productButton = new JButton("Products"); productButton.setBounds(100, 170, 80, 25); home.add(productButton); customerButton = new JButton("Customers"); customerButton.setBounds(100, 200, 80, 25); home.add(customerButton); Home.setVisible(true); } private static void setDefaultCloseOperation(int EXIT_ON_CLOSE) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } static class Invoice1 extends Home { PopupMenu Invoice1; public Invoice1() { } } static void setVisible(boolean b) { } private static void getInvoice1() { } }
解决方案
问题根源
- Home类结构错误:Home并非JFrame子类,没有实际创建窗口实例,静态方法
setVisible为空实现,调用Home.setVisible(true)无法显示有效窗口。 - 继承关系混乱:Invoice1继承Home无实际意义,且注册页仅隐藏面板而非关闭窗口。
- SQL语句风险:注册数据插入采用字符串拼接,存在SQL注入风险。
修改后的代码
Home.java
package invoice1; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class Home extends JFrame { private JLabel homeLabel ; private JButton invoiceButton; private JButton invoiceHistory; private JButton statementButton; private JButton statementHistory; private JButton productButton; private JButton customerButton; public Home() { // 初始化窗口属性 setTitle("Invoice System - Home"); setSize(400, 300); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); // 居中显示 JPanel homePanel = new JPanel(); homePanel.setLayout(null); add(homePanel); // 添加主页组件 homeLabel = new JLabel("HOME"); homeLabel.setBounds(150, 20, 80, 25); homePanel.add(homeLabel); invoiceButton = new JButton("Create Invoice"); invoiceButton.setBounds(120, 50, 150, 25); homePanel.add(invoiceButton); statementButton = new JButton("Create Statement"); statementButton.setBounds(120, 80, 150, 25); homePanel.add(statementButton); invoiceHistory = new JButton("Invoice History"); invoiceHistory.setBounds(120, 110, 150, 25); homePanel.add(invoiceHistory); statementHistory = new JButton("Statement History"); statementHistory.setBounds(120, 140, 150, 25); homePanel.add(statementHistory); productButton = new JButton("Products"); productButton.setBounds(120, 170, 150, 25); homePanel.add(productButton); customerButton = new JButton("Customers"); customerButton.setBounds(120, 200, 150, 25); homePanel.add(customerButton); } public static void main(String[] args) { // 启动主页 new Home().setVisible(true); } }
Invoice1.java
package invoice1; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.sql.*; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; public class Invoice1 { private static JLabel nameLabel; private static JTextField nameText; private static JLabel passwordLabel; private static JTextField passwordText; private static JButton button; private static JFrame frame; // 保存注册窗口实例 public static void main(String[] args) { frame = new JFrame("Create Account"); frame.setSize(350, 200); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLocationRelativeTo(null); JPanel panel = new JPanel(); panel.setLayout(null); frame.add(panel); nameLabel = new JLabel("Business Name"); nameLabel.setBounds(10, 20, 80, 25); panel.add(nameLabel); nameText = new JTextField(40); nameText.setBounds(100, 20, 165, 25); panel.add(nameText); passwordLabel = new JLabel ("Create Password"); passwordLabel.setBounds (10, 50, 80, 25); panel.add(passwordLabel); passwordText = new JTextField(20); passwordText.setBounds(100, 50, 165, 25); panel.add(passwordText); button = new JButton("Create Account"); button.setBounds(130, 110, 120, 25); button.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e){ String name = nameText.getText(); String password = passwordText.getText(); if (name.isEmpty() || password.isEmpty()) { JOptionPane.showMessageDialog(frame, "Please fill all fields"); return; } if (addToDB(name, password)) { JOptionPane.showMessageDialog(frame, "Account Created!"); // 关闭注册窗口,启动主页 frame.dispose(); new Home().setVisible(true); } else { JOptionPane.showMessageDialog(frame, "Failed to create account"); } } }); panel.add(button); frame.setVisible(true); } // 插入数据到数据库,返回操作结果 public static boolean addToDB(String un, String pass){ Connection dbCon = null; String strUrl = "jdbc:sqlite:testDB.db"; try{ dbCon = DriverManager.getConnection(strUrl); // SQLite无需用户名密码 System.out.println("Connected to database"); // 使用PreparedStatement防止SQL注入 String insertSql = "INSERT INTO loginDetails (username, password) VALUES (?, ?)"; PreparedStatement stmt = dbCon.prepareStatement(insertSql); stmt.setString(1, un); stmt.setString(2, pass); int affectedRows = stmt.executeUpdate(); return affectedRows > 0; }catch(SQLException e){ e.printStackTrace(); return false; } finally { try { if (dbCon != null) dbCon.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
修改说明
- Home类重构:改为继承JFrame,在构造方法中完成窗口和组件初始化,确保调用
new Home().setVisible(true)能显示完整主页。 - 注册页优化:移除不必要的继承关系,保存注册窗口实例,注册成功后直接关闭窗口并启动主页。
- 数据库操作优化:使用PreparedStatement替代字符串拼接,避免SQL注入风险,同时返回操作结果以便判断注册是否成功。
- 用户体验提升:增加空字段校验,窗口居中显示,按钮尺寸调整更合理。
内容的提问来源于stack exchange,提问作者Kate Murphy
相关产品推荐
相关产品推荐

