why the frame will confused!![:-)]
these are my classes.when i run my MainClient class,one frame will be shown that get text from client and then send it to the server.at the first time when i click on the Send button,it will work correctly and send data to the server but suddenly the frame will confused and I can not do any thing like writing or clicking on the button!!please help me.
MainClient class:
//these are in the main(String[] args)
MainFrame farme = new MainFrame();
farme.setVisible(true);
c = new Socket("localhost", 5050);
os = new PrintWriter(c.getOutputStream(), true);
is = new BufferedReader(new InputStreamReader(c.getInputStream()));
//this method is not in the main(String[] arg开发者_如何学运维s)
public static void active() {
String teXt = MainClient.getText();
System.out.println(teXt);
os.println(teXt);
String line = is.readLine();
System.out.println("Text received: " + line);
}
my gui class which get text from client and by clicking on the send button will send that text to the server:(Send button action performed)
public ChatFrame(InformationClass client) {
initComponents();
jButton1.setEnabled(false);
this.client = client;
jTextArea2.setText("");
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
submit();
clear();
}
private void submit() {
String text = jTextArea1.getText();
jTextArea2.append(client.getCurrentName() + " : " + text + "\n");
MainClient.setText(client.getCurrentName() + " : " + text + "\n");
MainClient.active();
}
private void clear() {
jTextArea1.setText("");
}
The MainClient.active() call is blocking waiting for the Socket to respond. Because it is called in the ActionListener it is blocking the Swing event dispatch thread on which all UI events are triggered. This is causing the UI to be unresponsive.
If you can you should use SwingWorker to perform the blocking task in a background thread. See the documentation here:
http://java.sun.com/javase/6/docs/api/javax/swing/SwingWorker.html
If SwingWorker is not available then you can do it with something like this:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
new Thread(new Runnable() {
@Override
public void run() {
// This gets run in a background thread
String text = jTextArea1.getText();
jTextArea2.append(client.getCurrentName() + " : " + text + "\n");
MainClient.setText(client.getCurrentName() + " : " + text + "\n");
MainClient.active();
}
}).start();
}
That is an ugly way to do it but it is also the shortest and will work on any version of Java that has Swing.
Edit: The clear method has to be called on the event dispatch thread as it accesses a UI component - jTextArea1.setText(""). To make it run on the EDT do this:
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
clear();
}
});
Anonymous inner classes are ugly especially when they are inside other anonymous inner classes but they are convenient for code samples. In your actual implementation you should create a class that implements Runnable to do the original background task to make the code more readable.
Closures in Java 7 should make this sort of task a lot less cluttered.
I'd bet your problem stems from all the IO objects you didn't close. Try flushing and closing your Reader and Writer objects.
os.Flush();
os.Close();
is.Flush();
is.Close();
Also, close your socket connection.
c.Close();
精彩评论