为什么 JOptionPane.showMessageDialog() 在我的程序中不起作用?

问题描述 投票:0回答:1

我的程序是一个模拟网上购物系统。该程序在运行时会显示登录屏幕,如果用户忘记了登录信息,可以单击“忘记密码”按钮。单击此按钮后,程序会打开一个框架,用户可以在其中输入他们的电子邮件地址。当用户输入此电子邮件地址并点击“发送密码恢复电子邮件”时,应该会出现一个消息对话框,通知用户电子邮件已成功发送(如果用户输入的电子邮件地址实际与他们的 ID)或未发送(如果用户输入的地址在数据库中不存在或不存在或与其他用户绑定)。但是,当我运行该程序时,没有弹出消息对话框,我也不知道为什么。没有返回异常 - 程序只是拒绝显示对话框。

这里是程序所有相关部分的代码。很抱歉提供了这么多代码,但由于程序没有返回异常,所以我不知道导致程序出现故障的代码在哪里。该程序还有其他部分,但它们与“忘记密码”屏幕没有直接关系。

应用:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.*;

public class Application {

    private static Application instance;   // Singleton pattern

    private static boolean checkEmail = false;

    private static String email;

    public static Application getInstance() {
        if (instance == null) {
            instance = new Application();
        }
        return instance;
    }
    // Main components of this application

    private Connection connection;

    public Connection getConnection() {
        return connection;
    }

    public static void setCheckEmail() {
        checkEmail = true;
    }

    public static void setEmail(String theEmail) {
        email = theEmail;
    }

    private DataAdapter dataAdapter;

    private User currentUser = null;

    public void setCurrentUser(User user) {
        this.currentUser = user;
    }

    public User getCurrentUser() {
        return currentUser;
    }

    // Create the Product View and Controller here!

    private ProductView productView = new ProductView();

    private CheckoutScreen checkoutScreen = new CheckoutScreen();

    private MainScreen mainScreen = new MainScreen();

    public MainScreen getMainScreen() {
        return mainScreen;
    }

    public ProductView getProductView() {
        return productView;
    }

    public CheckoutScreen getCheckoutScreen() {
        return checkoutScreen;
    }

    public LoginScreen loginScreen = new LoginScreen();

    public LoginScreen getLoginScreen() {
        return loginScreen;
    }

    public LoginController loginController; // = new LoginController(loginScreen, dataAdapter);

    private ProductController productController;

    public ProductController getProductController() {
        return productController;
    }

    private CheckoutController checkoutController;

    public CheckoutController getCheckoutController() {
        return checkoutController;
    }

    public DataAdapter getDataAdapter() {
        return dataAdapter;
    }

    private ForgotPasswordScreen forgotPasswordScreen = new ForgotPasswordScreen();

    public ForgotPasswordScreen getForgotPasswordScreen() {
        return forgotPasswordScreen;
    }

    private void initializeDatabase(Statement stmt) throws SQLException { // CHANGE: Added initialization code
        // create the tables and insert sample data here!

        stmt.execute("create table Product (ProductID int PRIMARY KEY, ProductName char(30), Price double, Quantity double);");
        stmt.execute("create table Orders (ProductID int PRIMARY KEY, ProductName char(30), Price double, Quantity double);");
        stmt.execute("create table OrderLine (OrderID INT NOT NULL, ProductID INT NOT NULL, Quantity double, Cost double, PRIMARY KEY (ProductID, OrderID);");
        stmt.execute("create table User (UserID INT NOT NULL, UserName CHAR(30) NOT NULL, Password CHAR(30) NOT NULL, DisplayName CHAR(30), IsManager BOOL DEFAULT FALSE, PRIMARY KEY(UserID));");
        stmt.execute("create table sqlite_sequence (name, seq);");
        stmt.execute("INSERT INTO Product VALUES (1, 'Apple', 1.0, 257.0), (2, 'Chair', 100.0, 38.0), (3, 'Smartphone', 699.99, 486.0), (4, 'T-shirt', 20.0, 244.0), (5, 'TV', 250.0, 43.0);");
        stmt.execute("INSERT INTO User VALUES (1, 'admin', 'password', 'Admin', TRUE);");


    }

    private void initializeEmailList(Statement stmt) throws SQLException {
        stmt.execute("CREATE TABLE Email (Email CHAR(30) NOT NULL, UserID int NOT NULL);");
        stmt.execute("INSERT INTO Email VALUES('[email protected]', 1);");
    }

    private Application() {
        // create SQLite database connection here!
        try {
            Class.forName("org.sqlite.JDBC");
            connection = DriverManager.getConnection("jdbc:sqlite:store.db");
            Statement stmt = connection.createStatement();
            if (!stmt.executeQuery("select * from product").next()) // product table do not exist
                initializeDatabase(stmt);
            if (!stmt.executeQuery("select * from email").next()) // product table do not exist
                initializeEmailList(stmt);
            if(checkEmail == true) {
                Statement stmt2 = connection.createStatement();
                ResultSet resultSet = stmt2.executeQuery("SELECT * from Email WHERE UserID = " + Application.getInstance().getCurrentUser().getUserID());
                if (!resultSet.next())
                    JOptionPane.showMessageDialog(null, "This email does not belong to any registered user!");
                else if (resultSet.getString(1) != email) JOptionPane.showMessageDialog(null, "Incorrect email!");
                else JOptionPane.showMessageDialog(null, "Email sent!");
                //Application.getInstance().checkEmail(email);
                checkEmail = false;
            }


        }
        catch (ClassNotFoundException ex) {
            System.out.println("SQLite is not installed. System exits with error!");
            System.exit(1);
        }

        catch (SQLException ex) {
            System.out.println("SQLite database is not ready. System exits with error!" + ex.getMessage());

            System.exit(2);
        }

        // Create data adapter here!
        dataAdapter = new DataAdapter(connection);

        productController = new ProductController(productView, dataAdapter);

        checkoutController = new CheckoutController(checkoutScreen, dataAdapter);

        loginController = new LoginController(loginScreen, dataAdapter);
    }


    public static void main(String[] args) {
        Application.getInstance().getLoginScreen().setVisible(true);
    }
}

忘记密码控制器:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.*;

public class ForgotPasswordController implements ActionListener {
    private ForgotPasswordScreen forgotPasswordScreen;

    public ForgotPasswordController(ForgotPasswordScreen forgotPasswordScreen) {
        this.forgotPasswordScreen = forgotPasswordScreen;
        this.forgotPasswordScreen.getSendEmail().addActionListener(this);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == forgotPasswordScreen.getSendEmail()) {
            String email = forgotPasswordScreen.getEmailAddress().getText().trim();
            Application.setEmail(email);
            Application.setCheckEmail();
            /*Connection forgotPasswordConnection = Application.getInstance().getConnection();
            Statement stmt = forgotPasswordConnection.createStatement();
            ResultSet resultSet = stmt.executeQuery("SELECT * from Email WHERE UserID = " + Application.getInstance().getCurrentUser().getUserID());
            if (!resultSet.next())
                JOptionPane.showMessageDialog(null, "This email does not belong to any registered user!");
            else if (resultSet.getString(1) != email) JOptionPane.showMessageDialog(null, "Incorrect email!");
            else JOptionPane.showMessageDialog(null, "Email sent!");*/
            //Application.getInstance().checkEmail(email);
            Application application = Application.getInstance();
        }
    }
}

忘记密码屏幕:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ForgotPasswordScreen extends JFrame {
    private JTextField emailAddress = new JTextField(30);

    private JButton sendEmail = new JButton("Send Password Recovery Email");

    public JButton getSendEmail() {
        return sendEmail;
    }

    public JTextField getEmailAddress() {
        return emailAddress;
    }

    public ForgotPasswordScreen() {
        this.setLayout(new BoxLayout(this.getContentPane(), BoxLayout.Y_AXIS));
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(400, 200);

        JPanel panelForgotPasswordScreen = new JPanel();

        JLabel emailAddressLabel = new JLabel("Email address:");

        panelForgotPasswordScreen.add(emailAddressLabel);
        panelForgotPasswordScreen.add(emailAddress);

        this.getContentPane().add(panelForgotPasswordScreen);

        JPanel panelSendEmailButton = new JPanel();
        panelSendEmailButton.add(sendEmail);

        this.getContentPane().add(sendEmail);

    }
}

登录控制器:

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class LoginController implements ActionListener {
    private LoginScreen loginScreen;
    private DataAdapter dataAdapter;


    public LoginController(LoginScreen loginScreen, DataAdapter dataAdapter) {
        this.loginScreen = loginScreen;
        this.dataAdapter = dataAdapter;
        this.loginScreen.getBtnLogin().addActionListener(this);
        this.loginScreen.getBtnForgotPassword().addActionListener(this);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == loginScreen.getBtnLogin()) {
            String username = loginScreen.getTxtUserName().getText().trim();
            String password = loginScreen.getTxtPassword().getText().trim();

            System.out.println("Login with username = " + username + " and password = " + password);
            User user = dataAdapter.loadUser(username, password);

            if (user == null) {
                JOptionPane.showMessageDialog(null, "This user does not exist!");
            }
            else {
                Application.getInstance().setCurrentUser(user);
                this.loginScreen.setVisible(false);
                Application.getInstance().getMainScreen().setVisible(true);
            }
        }
        if(e.getSource() == loginScreen.getBtnForgotPassword()) {
            Application.getInstance().getForgotPasswordScreen().setVisible(true);
        }
    }
}

登录屏幕:

import javax.swing.*;
import java.awt.*;

public class LoginScreen extends JFrame {
    private JTextField txtUserName = new JTextField(10);
    private JTextField txtPassword = new JTextField(10);
    private JButton    btnLogin    = new JButton("Login");
    private JButton btnForgotPassword = new JButton("Forgot Password"); //CHANGE: Added a mechanism for the user to recover a forgotten password

    public JButton getBtnLogin() {
        return btnLogin;
    }

    public JTextField getTxtPassword() {
        return txtPassword;
    }

    public JTextField getTxtUserName() {
        return txtUserName;
    }

    public JButton getBtnForgotPassword() {
        return btnForgotPassword;
    }

    public LoginScreen() {


        this.setSize(300, 400);
        this.setLayout(new BoxLayout(this.getContentPane(), BoxLayout.Y_AXIS));

        this.getContentPane().add(new JLabel ("Store Management System"));

        JPanel panelUserName = new JPanel();
        panelUserName.add(new JLabel("Username:"));
        panelUserName.add(txtUserName);

        this.getContentPane().add(panelUserName);

        JPanel panelPassword = new JPanel();
        panelPassword.add(new JLabel("Password:"));
        panelPassword.add(txtPassword);

        this.getContentPane().add(panelPassword);

        JPanel panelLogin = new JPanel();
        panelLogin.setAlignmentX(Component.CENTER_ALIGNMENT); //CHANGE: Centered the login and "forgot password" buttons
        panelLogin.add(btnLogin);

        JPanel panelForgotPassword = new JPanel();
        panelLogin.setAlignmentX(Component.CENTER_ALIGNMENT);
        panelForgotPassword.add(btnForgotPassword);

        this.getContentPane().add(panelLogin);
        this.getContentPane().add(panelForgotPassword);
    }
}

编辑:按照 MadProgrammer 的建议,我从 Application 类中删除了测试用户输入的电子邮件地址有效性的代码,并将其添加到 actionPerformed 方法内的 ForgotPasswordController 类中;但是,我现在收到一个新错误:“未报告的异常 java.sql.SQLException;必须被捕获或声明为被抛出”。

在 actionPerformed 方法中添加“throws SQLException”在诊断问题时不起作用,因为它覆盖的方法不包括“throws SQLException”;这样做只会产生一个新错误,提示“java: actionPerformed(java.awt.event.ActionEvent) in ForgotPasswordController cannot implement actionPerformed(java.awt.event.ActionEvent) in java.awt.event.ActionListener 重写的方法不会抛出 java.sql.SQLException”。

这是我的 actionPerformed 方法的新代码:

@Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == forgotPasswordScreen.getSendEmail()) {
            String email = forgotPasswordScreen.getEmailAddress().getText().trim();
            //Application.setEmail(email);
            //Application.setCheckEmail();
            /*Connection forgotPasswordConnection = Application.getInstance().getConnection();
            Statement stmt = forgotPasswordConnection.createStatement();
            ResultSet resultSet = stmt.executeQuery("SELECT * from Email WHERE UserID = " + Application.getInstance().getCurrentUser().getUserID());
            if (!resultSet.next())
                JOptionPane.showMessageDialog(null, "This email does not belong to any registered user!");
            else if (resultSet.getString(1) != email) JOptionPane.showMessageDialog(null, "Incorrect email!");
            else JOptionPane.showMessageDialog(null, "Email sent!");*/
            //Application.getInstance().checkEmail(email);
            //Application application = Application.getInstance();
            Connection connection = DriverManager.getConnection("jdbc:sqlite:store.db");
            Statement stmt = connection.createStatement();
            ResultSet resultSet = stmt.executeQuery("SELECT * from Email WHERE UserID = " + Application.getInstance().getCurrentUser().getUserID());
            if (!resultSet.next())
                JOptionPane.showMessageDialog(null, "This email does not belong to any registered user!");
            else if (resultSet.getString(1) != email) JOptionPane.showMessageDialog(null, "Incorrect email!");
            else JOptionPane.showMessageDialog(null, "Email sent!");
        }
    }
java sql database swing joptionpane
1个回答
0
投票

让我们去掉一些噪音,仔细看看这个……

public class Application {

    private static Application instance;   // Singleton pattern

    private static boolean checkEmail = false;
    private static String email;

    public static Application getInstance() {
        if (instance == null) {
            instance = new Application();
        }
        return instance;
    }

    public Connection getConnection() {
        return connection;
    }

    private Application() {
        // create SQLite database connection here!
        try {
            Class.forName("org.sqlite.JDBC");
            connection = DriverManager.getConnection("jdbc:sqlite:store.db");
            Statement stmt = connection.createStatement();
            if (!stmt.executeQuery("select * from product").next()) // product table do not exist
            {
                initializeDatabase(stmt);
            }
            if (!stmt.executeQuery("select * from email").next()) // product table do not exist
            {
                initializeEmailList(stmt);
            }
            if (checkEmail == true) {
                Statement stmt2 = connection.createStatement();
                ResultSet resultSet = stmt2.executeQuery("SELECT * from Email WHERE UserID = " + Application.getInstance().getCurrentUser().getUserID());
                if (!resultSet.next()) {
                    JOptionPane.showMessageDialog(null, "This email does not belong to any registered user!");
                } else if (resultSet.getString(1) != email) {
                    JOptionPane.showMessageDialog(null, "Incorrect email!");
                } else {
                    JOptionPane.showMessageDialog(null, "Email sent!");
                }
                //Application.getInstance().checkEmail(email);
                checkEmail = false;
            }

        } catch (ClassNotFoundException ex) {
            System.out.println("SQLite is not installed. System exits with error!");
            System.exit(1);
        } catch (SQLException ex) {
            System.out.println("SQLite database is not ready. System exits with error!" + ex.getMessage());

            System.exit(2);
        }

        // Create data adapter here!
        dataAdapter = new DataAdapter(connection);

        productController = new ProductController(productView, dataAdapter);

        checkoutController = new CheckoutController(checkoutScreen, dataAdapter);

        loginController = new LoginController(loginScreen, dataAdapter);
    }

    public static void main(String[] args) {
        Application.getInstance().getLoginScreen().setVisible(true);
    }
}

所以,在

main
方法中你调用
Application.getInstance().getLoginScreen().setVisible(true);

这将:

  • 创建
    Application
    的新实例(在
    getInstance
    中)
  • 构造函数将初始化数据库和其他内部状态,但由于
    checkEmail
    默认为
    false
    ,它不会执行该工作流
  • 显示登录画面

最终,我们发现自己在这里......

@Override
public void actionPerformed(ActionEvent e) {
    if (e.getSource() == forgotPasswordScreen.getSendEmail()) {
        String email = forgotPasswordScreen.getEmailAddress().getText().trim();
        Application.setEmail(email);
        Application.setCheckEmail();
        Application application = Application.getInstance();
    }
}

现在,问题是,当你调用

Application.getInstance()
时,你将取回之前创建的实例(回到调用
main
时,有点像单例),所以构造函数是从来没有叫过。

相反,你应该有一个专门的方法来处理忘记的密码,也许更像是......

public enum Application {
    INSTANCE;

    private Connection connection;
    private User currentUser = null;

    private Application() {
        // Setup and initialisation
    }

    public Connection getConnection() {
        return connection;
    }

    // Not sure this makes sense to me, unless the authentication
    // workflow is seperate from the Application, I'd probably not
    // allow the user to be set here, but that's me
    public void setCurrentUser(User user) {
        this.currentUser = user;
    }

    public User getCurrentUser() {
        return currentUser;
    }

    public void recoverAccount(String email) throws Exception {
        try (PreparedStatement stmt = connection.prepareStatement("SELECT * from Email WHERE UserID = ?")) {
            // How do you get the current userId for a user whose not logged in?
            // I smell a NullPointerException in your future
            stmt.setInt(1, getCurrentUser().getUserID());
            try (ResultSet rs = stmt.executeQuery()) {
                // Personally, I'd throw customised exceptions here, as they are
                // easier to deal with
                if (!resultSet.next()) {
                    throw Exception("This email does not belong to any registered user!");
                } else if (resultSet.getString(1) != email) {
                    throw Exception("Incorrect email!");
                }
            }
        }
    }
    // Other functionality not implemented
}

然后你只需调用

Application.INSTANCE.recoverAccount(someEmailAddress);
...但请注意,这会抛出一个
Exception

© www.soinside.com 2019 - 2024. All rights reserved.