我有一个需要登录用户的应用程序。数据存储在Derby DB中。下面的表单根据用户名和密码字段查询它,并设置用户会话,该会话应填充用户数据。
但是,即使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!!!
}
});
}
}
答案 0 :(得分:2)
如果你真正想要的是将输出输出到控制台,那么你应该将它放在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();
}
}
然后将main方法更改为:
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();
}
答案 1 :(得分:1)
您遇到的问题是因为您在用户有机会填写表单并按“提交”按钮之前尝试获取会话。
当按下提交按钮时,将异步调用处理程序,在创建表单后将直接调用main中的println。您要么必须等到会话不再为null,要么在处理程序中使用经过身份验证的会话。