使用多线程实现java gui登录 [英] Implementing java gui login using multithreading

查看:89
本文介绍了使用多线程实现java gui登录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个 java 应用程序,它在 jframe 中有一个登录表单.我有文本字段和按钮.

I am working on a java application which has a login form in a jframe. I have text fields and buttons in it.

登录按钮有一个事件监听器,它是创建登录窗口的类的内部类.当用户按下登录按钮时,侦听器从字段中获取值并将其传递给验证器,该验证器使用 mysql 数据库对其进行验证,并根据用户的输入返回 true 和 false.现在,基于返回值,侦听器使用 if-else 语句更新 ui.一切正常.

The login button has an eventlistener which is an inner-class of the class that creates the login window. When user presses the login button, the listener takes the values form the fields and passes it to a validator which validates it using a mysql database and returns true and false based on the input by user. Now based on the return value the listener updates the ui using the if-else statement. This whole thing is working is fine.

问题是在执行验证时无法使用 gui,因为每件事都是用单个线程完成的.所以那个时候 gui 有点冻结.如何使用多线程来避免此问题并在执行验证时使用其他 gui 组件.

The problem is that when the validation is being carried out the gui cannot be used, because every thing is being done with a single thread. So for that time the gui is kind of freezed. How can I use multithreading to avoid this problem and use other gui components while validation is carried out.

推荐答案

您可能知道,永远不要在事件调度线程中执行长时间运行的任务,这会让您的程序看起来像是挂了.

As you're probably aware, you should never perform long running tasks within the Event Dispatching Thread, this makes you program look like its hung.

同样,您永远不应该在事件调度线程之外创建/修改任何 UI 组件.

Equally, you should never create/modify any UI component outside the Event Dispatching Thread.

最简单的解决方案之一是使用 SwingWorker.这允许您在后台线程中执行代码,但它会自动将其结果重新同步回事件调度线程...

One of the simplest solutions would be to use a SwingWorker. This allows you execute code in a background thread, but it will automatically resync it's results back the Event Dispatching Thread...

public class LoginForm {

    public static void main(String[] args) {
        new LoginForm();
    }

    public LoginForm() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

                JDialog frame = new JDialog((JFrame) null, "Login", true);
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new LoginPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                System.exit(0);
            }
        });
    }

    public class LoginPane extends JPanel {

        private JTextField userNameField;
        private JPasswordField passwordField;
        private JButton okay;
        private JButton cancel;

        public LoginPane() {

            setLayout(new BorderLayout());

            userNameField = new JTextField(15);
            passwordField = new JPasswordField(10);

            okay = new JButton("Login");
            cancel = new JButton("Cancel");

            JPanel mainPane = new JPanel(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.anchor = GridBagConstraints.EAST;
            gbc.insets = new Insets(2, 2, 2, 2);
            mainPane.add(new JLabel("User Name:"), gbc);
            gbc.gridy++;
            mainPane.add(new JLabel("Password:"), gbc);

            gbc.gridx++;
            gbc.gridy = 0;
            gbc.anchor = GridBagConstraints.WEST;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            mainPane.add(userNameField, gbc);
            gbc.gridy++;
            mainPane.add(passwordField, gbc);
            mainPane.setBorder(new EmptyBorder(8, 8, 8, 8));

            add(mainPane);

            JPanel buttonPane = new JPanel(new FlowLayout(FlowLayout.RIGHT));
            buttonPane.setBorder(new EmptyBorder(8, 8, 8, 8));
            buttonPane.add(okay);
            buttonPane.add(cancel);

            add(buttonPane, BorderLayout.SOUTH);

            okay.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    userNameField.setEnabled(false);
                    passwordField.setEnabled(false);
                    okay.setEnabled(false);
                    cancel.setEnabled(false);
                    new LoginWorker(userNameField.getText(), passwordField.getPassword()).execute();
                }
            });

            cancel.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    SwingUtilities.getWindowAncestor(LoginPane.this).dispose();
                }
            });
        }

        public class LoginWorker extends SwingWorker<Boolean, Boolean> {

            private String userName;
            private char[] password;

            public LoginWorker(String userName, char[] password) {
                this.userName = userName;
                this.password = password;
            }

            @Override
            protected Boolean doInBackground() throws Exception {
                // Do you background work here, query the database, compare the values...
                Thread.sleep(2000);
                return Math.round((Math.random() * 1)) == 0 ? new Boolean(true) : new Boolean(false);
            }

            @Override
            protected void done() {
                System.out.println("Done...");
                try {
                    if (get()) {
                        JOptionPane.showMessageDialog(LoginPane.this, "Login sucessful");
                    } else {
                        JOptionPane.showMessageDialog(LoginPane.this, "Login failed");
                    }
                    userNameField.setEnabled(true);
                    passwordField.setEnabled(true);
                    okay.setEnabled(true);
                    cancel.setEnabled(true);
                } catch (Exception exp) {
                    exp.printStackTrace();
                }
            }

        }

    }
}

查看Swing 中的并发 了解更多信息,特别是 SwingWorker

Take a look at Concurrency in Swing for more information, in particular, SwingWorker

这篇关于使用多线程实现java gui登录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆