为什么JButton被点击后变为非活动状态?
问题描述:
输入用户的用户名和密码后,单击按钮将流发送到服务器以确定是否应该对用户进行身份验证。该按钮停止工作,就像它已被禁用。为什么JButton被点击后变为非活动状态?
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();
}
}
答
你ActionListener
被连接到Socket
。 A Socket
阻止等待输入。由于此代码在Event Dispatch Thread (EDT)
上执行,因此GUI会冻结。
解决方案是在单独的Thread
中连接到您的Socket
。
有关EDT
的更多信息,请参阅Concurrency上的Swing教程。您可能需要考虑使用SwingWorker
作为您的Thread
。在需要时,使用SwingWorker
API可以更轻松地更新GUI。
我对actionPerformed方法进行了更改。现在GUI在被点击后不会冻结。但是,服务器仅在点击按钮后才会响应一次。在随后的点击中,没有任何内容从服务器发送到客户端。你能告诉我什么可能导致这种情况发生? – KMuir
@KMuir要使用套接字,您需要一个“while循环”来持续等待来自套接字的数据。看看[Java教程](http://docs.oracle.com/javase/tutorial/index.html)。有'套接字'部分让你开始。 – camickr