0

ユーザーのログインが必要なアプリケーションがあります。データは Derby DB に保存されます。以下のフォームは、ユーザー名とパスワードのフィールドに基づいてクエリを実行し、ユーザー データを入力する必要があるユーザー セッションを設定します。

ただし、データベースがユーザーを認証しているにもかかわらず、セッションは null を返しています。コードをすぐに実行してnullを返すのではなく、データベースクエリに基づいてセッションデータを返すこのクラスのメインメソッドにsystem.out.printlnを配置するにはどうすればよいですか?

注: データベースは正しく機能しています。SQL ステートメントのユーザー名とパスワードのフィールドに基づいて結果を取得できます。

public class LoginForm{

    private static JTextField userName;
    private static JTextField password;
    private static JButton submit;
    private static int attempts;
    private static JFrame main;

    private Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();

    final int MAX_ATTEMPTS = 5;

    private UserSession session;

    public LoginForm(){

        Handler handle = new Handler();                             //inner class
        LoginFormFocusListener fl = new LoginFormFocusListener();   //inner class

        main = new JFrame();

        main.setUndecorated(true);
        main.setBounds((dim.width/2) - (500/2),(dim.height/2) - (150/2),500, 75);
        main.setVisible(true);
        main.setAlwaysOnTop(true);
        main.setResizable(false);
        main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        userName = new JTextField(10);
        password = new JTextField(10);
        main.setLayout(new GridLayout(0,1));

        JPanel panel = new JPanel();
        main.add(panel);

        panel.add(new JLabel("Username: "));
        panel.add(userName);
        panel.add(new JLabel("Password: "));
        panel.add(password);
        panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createBevelBorder(4), "Please Login"));

        submit = new JButton("Submit");
        panel.add(submit);

        if(attempts > 0){
            panel.add(new JLabel("" + (MAX_ATTEMPTS - attempts) + " attempts remaining..."));
        }

        main.addWindowFocusListener(fl);
        submit.addActionListener(handle);
    }



    public UserSession getSession(){
        return this.session;
    }

    /**
     * creates the session that's returned to main/POSsystem via getSession
     * @author Matt
     *
     */
    private class Handler implements ActionListener
    {
        @Override
        public void actionPerformed(ActionEvent e) {
            String user = userName.getText();
            String pass = password.getText();

            session = new UserSession();
            if(session.authenticate(user,  pass)){
                System.out.println("User has been authenticated");
                JOptionPane.showMessageDialog(null,"Login Successful! ","",JOptionPane.PLAIN_MESSAGE);
            }else{
                System.out.println("Login Failed!");
                JOptionPane.showMessageDialog(null,"Login Failed!","", JOptionPane.WARNING_MESSAGE);
                attempts++;
                if(attempts < MAX_ATTEMPTS){
                    new LoginForm();
                }else{
                    JOptionPane.showMessageDialog(null, "Max attempts reached.  " +
                                                        "Please Contact the administrator of this system. ",
                                                        "User Locked",
                                                        JOptionPane.ERROR_MESSAGE);
                }
            }
        }
    }

    /**
     * Inner Class
     * custom focus events for the login form
     * the user may click away from this pop-up to close it.
     * @author Matt
     *
     */
    public class LoginFormFocusListener implements WindowFocusListener{

        @Override
        public void windowGainedFocus(WindowEvent wEvt) {}

        @Override
        public void windowLostFocus(WindowEvent wEvt) {
            ((JFrame) wEvt.getSource()).dispose();
        } 
    }    

    //test
    public static void main(String args[]){

        SwingUtilities.invokeLater(new Runnable(){  
              public void run(){  
                LoginForm lf = new LoginForm();  
                System.out.println("Session: " + lf.getSession());    <---NULL!!!
              }  
            });  


    }

}
4

2 に答える 2

2

コンソールへの出力が本当に必要な場合は、System.out.println コードを main メソッドに配置する代わりに、actionPerformed メソッドの最後の行として配置する必要があります。

本当に、本当に、本当にそのコードを main メソッドに入れたい場合は、作成された LoginForm を取得できる Runnable インターフェースを実装するクラスを作成する必要があります。

このような:

final class InitThread implements Runnable {
LoginForm lf;

public LoginForm getLfForSystemOut() {
    while (lf == null) {
        try {
            Thread.sleep(500);
        } catch (final InterruptedException e) {
            return null;
        }
    }
    synchronized (lf) {
        try {
            lf.wait();
            return lf;
        } catch (final InterruptedException e) {
            e.printStackTrace();
        }
    }
    return null;
}

@Override
public void run() {
    lf = new LoginForm();
}
}

次に、メイン メソッドを次のように変更します。

public static void main(final String args[]) {

    final InitThread init = new InitThread();
    SwingUtilities.invokeLater(init);

    System.out.println("Session: " + init.getLfForSystemOut().getSession());

}

最後に、このブロックの actionPerformed メソッドの最後に:

synchronized (LoginForm.this) {
    LoginForm.this.notifyAll();
}
于 2012-09-03T22:41:28.740 に答える
1

あなたが抱えている問題は、ユーザーがフォームに入力して [送信] ボタンを押す前にセッションを取得しようとしているためです。

ハンドラーは送信ボタンが押されると非同期で呼び出され、メインの println はフォームが作成された直後に呼び出されます。セッションが null でなくなるまで待つか、ハンドラーで認証済みセッションを使用する必要があります。

于 2012-09-03T22:29:04.883 に答える