Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
584 views
in Technique[技术] by (71.8m points)

java - Problems understanding the framework around a JXLoginPane example

I've found a component called JXLoginPane from SwingX available in WindowBuilder and that seems like it would be a good starting point for what I am trying to do, but I need more information about how to use it. So far, the only thing I've found to really help me out with it is this 9-year-old blog post.

It does get me most of the way there, but there are several references to things like is.IS_Statics, is.MD5Hash, and isquote.Main that the author does not provide. I am guessing that these are classes he or she has created just for logins, but I've no idea how to create them for myself.

How can I flesh out what Ruxton has started on his blog? Or, for that matter, can someone recommend an even better alternative to JXLoginPane?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

All answers will depend on your requirements, but most important thing is you understand what JXLoginPane is and how it works. Then you will be able to understand that 9 years old post:

  • JXLoginPane: creates a panel with controls to authenticate users in a login based application.

  • LoginService: abstract base class that has to do the log-in logic and determine if user authentication is valid or not. It keeps an internal list of LoginListeners object that are notified on LoginEvents during the whole login process: login started, canceled, succeeded and failed.

  • PasswordStore: abstract class intended to safely store passwords typed by users in some kind of cache, in order to help LoginService to authenticate users. The actual mechanism used to store the passwords is left up to the implementation.

  • UserNameStore: same as PasswordStore but for user names.

  • LoginListener: this interface provides a contract to "listen" the current login process and act in consequence. For example if a login attempt fails for the same user 5 times you could block that user assuming someone is trying to hack that account, or if login process succeeded then you could create a new session entry in your database if you are interested in keep a log table with users sessions.


Now taking a quick look to that post, I think it's a database service based implementation combined with Preferences based users names cache for UserNameStore:

  • Class is.ISLoginService is the LoginService abstract base class implementation.

  • Class is.ISUserNameStore is the UserNameStore abstract class implementation.

  • There's no implementation for PasswordStore abstract class.

  • Class is.ISLoginListener is a LoginListener interface implementation.

Finally, regarding is.IS_Statics, is.MD5Hash, and isquote.Main seem to be utility classes of that specific project and have nothing to do with the essentials of JXLoginPane. You will probably have your own classes that help you with login process.


Simple example

Please consider this simple example that illustrates the concepts above described. You will see is not that difficult to make it work.

Note: there's no user name nor password store implementations.
Note 2: see LoginAdapter

import java.awt.event.WindowEvent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import org.jdesktop.swingx.JXLoginPane;
import org.jdesktop.swingx.auth.LoginAdapter;
import org.jdesktop.swingx.auth.LoginEvent;
import org.jdesktop.swingx.auth.LoginListener;
import org.jdesktop.swingx.auth.LoginService;

public class Demo {

    private JFrame frame;
    private String userName;
    private int failedAttemptsCount = 0;

    private void showLoginDialog() {

        frame = new JFrame("Welcome!");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        final JXLoginPane loginPane = new JXLoginPane();

        LoginListener loginListener = new LoginAdapter() {
            @Override
            public void loginFailed(LoginEvent source) {
                failedAttemptsCount++;
                String message;
                switch(failedAttemptsCount) {
                    case 1: message = "Come on buddy! What happened?"; break;
                    case 2: message = "Did you just fail again?"; break;
                    case 3: message = "This is embarrassing..."; break;
                        default: message = "You should probably go home and get some sleep...";
                }
                loginPane.setErrorMessage(message);
            }

            @Override
            public void loginSucceeded(LoginEvent source) {
                Demo.this.userName = loginPane.getUserName();
                Demo.this.createAndShowGui();
            }
        };

        LoginService loginService = new LoginService() {
            @Override
            public boolean authenticate(String name, char[] password, String server) throws Exception {
                return name.equals("Sturm") 
                    && String.valueOf(password).equals("StackOverflow") ;
            }
        };

        loginService.addLoginListener(loginListener);
        loginPane.setLoginService(loginService);

        JXLoginPane.JXLoginDialog dialog = new JXLoginPane.JXLoginDialog(frame, loginPane);
        dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        dialog.setVisible(true);

        // if loginPane was cancelled or closed then its status is CANCELLED
        // and still need to dispose main JFrame to exiting application
        if(loginPane.getStatus() == JXLoginPane.Status.CANCELLED) {
            frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
        }
    }

    private void createAndShowGui() {
        String welcomeMessage = String.format("Welcome %s ! You have successfuly loged in.", userName);
        JPanel panel = new JPanel();
        panel.add(new JLabel(welcomeMessage));

        frame.add(panel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Demo().showLoginDialog();
            }
        });
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...