这些是我的类。当我运行我的MainClient类时,将显示一个框架,从客户端获取文本,然后将其发送到服务器。第一次单击“发送”按钮时,它将正常工作,发送数据到服务器,但突然框架会混淆,我不能做任何事情,如写或点击按钮!!请帮助我。
MainClient类:
//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[] args)
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);
}
我的gui类从客户端获取文本并单击发送按钮将该文本发送到服务器:(执行发送按钮操作)
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("");
}
答案 0 :(得分:3)
MainClient.active()调用阻止等待Socket响应。因为它在ActionListener中被调用,所以它阻止了触发所有UI事件的Swing事件调度线程。这导致UI无响应。
如果可以,您应该使用SwingWorker在后台线程中执行阻止任务。请参阅此处的文档:
http://java.sun.com/javase/6/docs/api/javax/swing/SwingWorker.html
如果SwingWorker不可用,那么你可以这样做:
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();
}
这是一种丑陋的方式,但它也是最短的,并且适用于任何具有Swing的Java版本。
编辑:必须在事件调度线程上调用clear方法,因为它访问UI组件 - jTextArea1.setText(“”)。要让它在EDT上运行,请执行以下操作:
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
clear();
}
});
匿名内部类很难看,特别是当它们在其他匿名内部类中时,但它们对代码示例很方便。在实际实现中,您应该创建一个实现Runnable的类来执行原始后台任务,以使代码更具可读性。
Java 7中的闭包应该使这类任务变得更加混乱。
答案 1 :(得分:0)
我敢打赌你的问题源于你没有关闭的所有IO对象。尝试刷新并关闭Reader和Writer对象。
os.Flush();
os.Close();
is.Flush();
is.Close();
另外,关闭套接字连接。
c.Close();