为什么JButton在点击后变为非活动状态?

时间:2017-04-03 03:20:39

标签: java swing sockets

输入用户的用户名和密码后,单击按钮将流发送到服务器以确定是否应对用户进行身份验证。该按钮停止工作,就像它被禁用一样。

public class EmployeeSignIn extends JFrame implements ActionListener {
    private JLabel lblUsername, lblPassword;
    private JTextField txtUsername;
    private JPasswordField jpfPassword;
    private JButton btnSubmit;
    private JPanel pnlButton, pnlLogo, pnlComponents1, pnlComponents2;
    private Socket socket;
    private ObjectOutputStream oos;
    private ObjectInputStream ois;

    private void initializeStreamComponents() {
        try {
            socket = new Socket("localhost", 4200);
            oos = new ObjectOutputStream(socket.getOutputStream());
            ois = new ObjectInputStream(socket.getInputStream());
        } catch (IOException e) {
            System.err.println(e.getMessage());
        }
    }

    private void initComponent() {
        initializeStreamComponents();

        lblUsername = new JLabel("Username");
        lblPassword = new JLabel("Password");

        txtUsername = new JTextField();

        jpfPassword = new JPasswordField();

        btnSubmit = new JButton("Sign In");

        pnlButton = new JPanel();
        pnlLogo = new JPanel(new GridLayout(1, 2));
        pnlComponents1 = new JPanel(new GridLayout(1, 2, 3, 3));
        pnlComponents2 = new JPanel(new GridLayout(1, 2, 3, 3));
    }

    private void addComponentsToPanel() {

        pnlLogo.add(new JLabel(new ImageIcon("img/app.png")));

        pnlComponents1.add(lblUsername);
        pnlComponents1.add(txtUsername);

        pnlComponents2.add(lblPassword);
        pnlComponents2.add(jpfPassword);

        pnlButton.add(btnSubmit);
    }

    private void addPanelsToWindow() {
        Container container = getContentPane();
        container.add(pnlLogo);
        container.add(pnlComponents1);
        container.add(pnlComponents2);
        container.add(pnlButton);
    }

    private void registerListeners() {
        btnSubmit.addActionListener(this);
    }

    private void setWindowProperties() {
        this.setTitle("ARD-Employee");
        this.setLayout(new GridLayout(4, 2));
        this.setVisible(true);
        this.setSize(450, 200);
        this.setResizable(false);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
    }

    public EmployeeSignIn() {
        this.initComponent();
        this.addComponentsToPanel();
        this.addPanelsToWindow();
        this.registerListeners();
        this.setWindowProperties();
    }

    private boolean validateFields() {
        if (!textFieldCheck(txtUsername)) {
            txtUsername.grabFocus();
            System.out.println(1);
            System.out.println("Please enter your username");
            System.out.println(2);
            return false;
        }

        if (!textFieldCharacterCheck(txtUsername)) {
            txtUsername.grabFocus();
            System.out.println("No Special Characters Allowed in Username!");
            return false;
        }

        if (!passwordFieldCheck(jpfPassword)) {
            jpfPassword.grabFocus();
            System.out.println("Please Enter your Password!");
            return false;
        }
        return true;
    }

    private boolean textFieldCheck(JTextField field) {
        if (field.getText().trim().isEmpty()) {
            field.grabFocus();
            return false;
        }
        return true;
    }

    private boolean passwordFieldCheck(JPasswordField field) {
        String password = new String(field.getPassword());
        if (password.trim().isEmpty()) {
            return false;
        }
        return true;
    }

    private boolean textFieldCharacterCheck(JTextField field) {
        return field.getText().matches("^\\d+$");
    }

    public String getUsername() {
        return txtUsername.getText();
    }

    public String getPassword() {
        return new String(jpfPassword.getPassword());
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        JButton src = (JButton) e.getSource();

        new Thread() {
            @Override
            public void run() {
                if (src.equals(btnSubmit)) {
                    if (validateFields()) {
                        sendStreamsToServer();
                    }
                }
            }
        }.start();
    }

    private void sendStreamsToServer() {
        try {

            String userType = "employee";
            oos.writeObject(userType);

            oos.writeObject(this.getUsername());
            System.out.println("USERNAME: " + this.getUsername());
            oos.writeObject(this.getPassword());
            System.out.println("PASSWORD: " + this.getPassword());

            String readObj = (String) ois.readObject();
            System.out.println("READ OBJECT: " + readObj);

            boolean validationCheck = (boolean) ois.readObject();
            System.out.println("Employee/VALIDATION CHECK: " + validationCheck);

        } catch (IOException e1) {
            System.err.println(e1.getMessage());
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private void closeConnection() {
        try {
            oos.close();
            ois.close();
        } catch (IOException e) {
            System.err.println(e.getMessage());
        }
    }

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

1 个答案:

答案 0 :(得分:4)

您的ActionListener正在与Socket相关联。一个Socket块等待输入。由于此代码在Event Dispatch Thread (EDT)上执行,因此GUI冻结。

解决方案是在单独的Socket

中连接到您的Thread

阅读Concurrency上Swing教程中的部分,了解有关EDT的更多信息。您可以考虑使用SwingWorker作为ThreadSwingWorker API可以在需要时更轻松地更新GUI。