Java 有线程和无线程并发

Java 有线程和无线程并发,java,concurrency,derby,Java,Concurrency,Derby,我有一个需要用户登录的应用程序。数据存储在Derby数据库中。下面的表单根据用户名和密码字段进行查询,并设置用户会话,该会话应填充用户数据 但是,即使db正在验证用户,会话仍返回null。我怎样才能将system.out.println放在此类的main方法中,该方法将基于db查询返回会话数据,而不是立即执行代码并返回null 注意:数据库工作正常。我可以根据sql语句中的用户名和密码字段获得结果 public class LoginForm{ private static JText

我有一个需要用户登录的应用程序。数据存储在Derby数据库中。下面的表单根据用户名和密码字段进行查询,并设置用户会话,该会话应填充用户数据

但是,即使db正在验证用户,会话仍返回null。我怎样才能将system.out.println放在此类的main方法中,该方法将基于db查询返回会话数据,而不是立即执行代码并返回null

注意:数据库工作正常。我可以根据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!!!
              }  
            });  


    }

}
公共类登录表单{
私有静态JTextField用户名;
私有静态JTextField密码;
私有静态JButton提交;
私有静态int尝试;
私有静态JFrame主机;
私有维度dim=Toolkit.getDefaultToolkit().getScreenSize();
最终int最大尝试次数=5次;
私人用户会话;
公共登录表单(){
Handler handle=new Handler();//内部类
LoginFormFocusListener fl=新LoginFormFocusListener();//内部类
main=新的JFrame();
主要。未装饰的设置(真实);
主立根((尺寸宽度/2)-(500/2),(尺寸高度/2)-(150/2),500,75);
main.setVisible(true);
main.setAlwaysOnTop(真);
main.setresizeable(false);
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
用户名=新的JTextField(10);
密码=新的JTextField(10);
main.setLayout(新网格布局(0,1));
JPanel面板=新的JPanel();
主。添加(面板);
添加(新的JLabel(“用户名:”);
panel.add(用户名);
添加(新的JLabel(“密码:”);
面板。添加(密码);
panel.setboorder(BorderFactory.createTitledBorder(BorderFactory.createbevelorder(4),“请登录”);
提交=新按钮(“提交”);
专家组。添加(提交);
如果(尝试次数>0){
添加(新JLabel(“+(最大尝试次数-尝试次数)+”剩余尝试次数…);
}
main.addWindowFocusListener(fl);
submit.addActionListener(句柄);
}
公共用户会话getSession(){
返回此会话;
}
/**
*创建通过getSession返回到main/POSsystem的会话
*@作者马特
*
*/
私有类处理程序实现ActionListener
{
@凌驾
已执行的公共无效操作(操作事件e){
字符串user=userName.getText();
字符串pass=password.getText();
session=newusersession();
if(会话身份验证(用户,通过)){
System.out.println(“用户已通过身份验证”);
showMessageDialog(null,“登录成功!”,“”,JOptionPane.PLAIN_消息);
}否则{
System.out.println(“登录失败!”);
JOptionPane.showMessageDialog(null,“登录失败!”,“”,JOptionPane.WARNING_消息);
尝试++;
如果(尝试次数<最大尝试次数){
新的LoginForm();
}否则{
showMessageDialog(null,“已达到最大尝试次数”)+
“请与此系统的管理员联系。”,
“用户锁定”,
JOptionPane.ERROR\u消息);
}
}
}
}
/**
*内部阶级
*登录表单的自定义焦点事件
*用户可以单击此弹出窗口以关闭它。
*@作者马特
*
*/
公共类LoginFormFocusListener实现WindowFocusListener{
@凌驾
公共无效windowGainedFocus(WindowEvent wEvt){}
@凌驾
公共无效windowLostFocus(WindowEvent wEvt){
((JFrame)wEvt.getSource()).dispose();
} 
}    
//试验
公共静态void main(字符串参数[]){
SwingUtilities.invokeLater(新的Runnable(){
public void run(){
LoginForm lf=新的LoginForm();

System.out.println(“Session:+lf.getSession());您遇到的问题是,您试图在用户有机会填写表单并按下提交按钮之前获取会话


当按下submit按钮时,将异步调用处理程序,创建表单后将直接调用main中的println。您必须等待会话不再为null,或者在处理程序中使用经过身份验证的会话。

您遇到的问题是因为您试图在e用户有机会填写表格并按下提交按钮


当按下submit按钮时,将异步调用处理程序,创建表单后将直接调用main中的println。您必须等待会话不再为null,或者在处理程序中使用经过身份验证的会话。

如果您真正想要的是将输出发送到控制台,而不是将main方法中的System.out.println代码应将其作为actionPerformed方法的最后一行

如果您真的、真的、真的希望在main方法中包含该代码,那么您应该创建一个实现Runnable接口的类,该接口允许获取创建的LoginForm

像这样:

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();
}

如果您真正想要的是将输出获取到控制台,那么您应该将System.out.println代码放在actionPerformed方法的最后一行,而不是放在main方法中

如果你真的,真的,真的想把代码放在主方法中