美好的一天,
我有一个无限循环的ServerSocket,工作正常…问题是当我尝试用一个按钮启动ServerSocket.我的用户界面“冻结”不动,任何东西,但服务器是正常的,这里我有一个ScreenShot:
http://i.gyazo.com/15d331166dd3f651fc7bda4e3670be4d.png
当我按下“Iniciar”按钮意味着启动服务器,用户界面冻结(ServerSocket无限循环).我无法更改我的代码,因为它的工作正常.
public static void iniciarServer() {
try {
appendString("\nServidor iniciado.");
System.out.println("asdasd");
} catch (BadLocationException e1) {
e1.printStackTrace();
}
try {
ss = new ServerSocket(1234, 3);
while (true) {
System.out.println("Esperando conexiones...");
appendString("\nEsperando conexiones...");
Socket s = ss.accept();
System.out.println("Conexión entrante: " + s.getRemoteSocketAddress());
appendString("\nConexión entrante: " + s.getRemoteSocketAddress());
conexiones++;
//System.out.println("Debug: conexiones SERVER: " + conexiones);
MultiThread mt = new MultiThread(s, conexiones);
mt.start();
///////////////////////////////////////////////////////////////
}
} catch (IOException e) {
System.out.println("Error Server: " + e.getMessage());
} catch (BadLocationException e) {
e.printStackTrace();
}
stopServer();
}
appendString();
用于向JTextPane添加一些文本,但由于UI冻结而无效.
有没有办法做一个不被无限循环冻结的用户界面?
谢谢!
解决方法:
Swing是一个单线程框架,这意味着在Event Dispatching Thread的上下文中执行的任何阻塞或长时间运行操作都将阻止它处理事件队列,从而使您的应用程序挂起.
它也不是线程安全的,所以你永远不应该尝试修改EDT外部的任何UI组件的状态.
有关详细信息,请查看Concurrency in Swing和Worker Threads and SwingWorker
public class ServerSocketWorker extends SwingWorker<Void, String> {
private JTextArea ta;
public ServerSocketWorker(JTextArea ta) {
this.ta = ta;
}
@Override
protected void process(List<String> chunks) {
for (String text : chunks) {
ta.append(text);
}
}
@Override
protected Void doInBackground() throws Exception {
ss = new ServerSocket(1234, 3);
while (true) {
publish("\nEsperando conexiones...");
Socket s = ss.accept();
publish("\nConexión entrante: " + s.getRemoteSocketAddress());
conexiones++;
//System.out.println("Debug: conexiones SERVER: " + conexiones);
MultiThread mt = new MultiThread(s, conexiones);
mt.start();
///////////////////////////////////////////////////////////////
}
}
@Override
protected void done() {
stopServer(); //??
}
}
要开始它,你可以使用像……
public void iniciarServer() {
ServerSocketWorker worker = new ServerSocketWorker(textAreaToAppendTo);
worker.execute();
}
举个例子