我有一個需要登錄用戶的應用程序。數據存儲在Derby數據庫中。下面的表格根據用戶名和密碼字段查詢它,並設置一個用戶會話,該會話應該填充用戶數據。有和沒有線程的併發
但是,即使db正在對用戶進行身份驗證,會話也會返回空值。我怎麼能把一個system.out.println放在這個類的主要方法中,它會根據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!!!
}
});
}
}
這是一個非常有用的解釋,並且幫助我更好地理解了線程。我的主要目標是簡單地將當前User對象分配給會話,但正如您所看到的,我無法獲取數據。當然,主要只是一個測試用例。我想將一個User obj分配給Session obj,但需要等待數據變爲可用。這導致我還有另一個問題......在更新數據時,我可以/應該從另一個類調用InitThread嗎?還是有另一種方式,我應該通過表單從數據庫中獲取數據? – Matt
如果您需要的是您從應用程序創建LoginForm以獲取UserSession的場景,那麼我建議您稍微改變一下設計。 你想要接收UserSession的地方應該有一個BlockingQueue [這裏](http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/BlockingQueue.html)對象和LoginForm在創建時應通過構造函數接收BlockingQueue。 然後主線程通過調用它的_take_方法等待BlockingQueue,直到LoginForm創建一個UserSession對象並使用_put_方法將其放入隊列。 – norbitheeviljester
謝謝你的建議。我一定會考慮使用BlockingQueue。我想我的設計可能不得不改變。再次感謝。 – Matt