我正在尝试从applet调用servlet,然后在applet gui中显示servlet的响应,问题是当我按下按钮调用servlet时GUI会阻塞,直到响应到达,我试试把请求的代码放在一个线程中,但是它会冻结gui,这就是代码:
public class SearchApplet extends JApplet implements ActionListener{
JTextField JTF_address;
public void init() {
JLabel JL_address = new JLabel("Address: ");
JL_address.setFont(new Font("OpenSans", Font.PLAIN, 16));
JTF_address = new JTextField(20);
....
}
public void actionPerformed(ActionEvent e) {
SearchThread search = new SearchThread();
search.run();
}
public class SearchThread implements Runnable {
public SearchThread() {
}
public void run() {
try {
String input = "prova";
URLConnection con = getServletConnection();
OutputStream outstream = con.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(outstream);
oos.writeObject(input);
oos.flush();
oos.close();
// receive result from servlet
InputStream instr = con.getInputStream();
ObjectInputStream inputFromServlet = new ObjectInputStream(instr);
String result = (String) inputFromServlet.readObject();
inputFromServlet.close();
instr.close();
// show result
JTF_address.setText(result);
} catch (Exception ex) {
ex.printStackTrace();
System.out.println(ex.toString());
}
}
}
}
我该怎么做?
答案 0 :(得分:1)
在您的actionPerformed
方法中,由于您的GUI冻结,您使用长时间运行的任务阻止Event Dispatch Thread
。对于后台进程,您可以使用SwingWorker
或ExecutorService
。这将在后台完成任务而不会冻结GUI。
另请阅读Concurrency in Swing。
答案 1 :(得分:1)
不要打电话
search.run();
呼叫
new Thread(search).start();
代替。
在你的actionPerformed中,你只是在当前线程中调用方法运行。如果你改为调用start(),它会执行魔术并启动执行run()的新线程。
然后你应该修改显示结果的方式,因为你不能在不是AwtEventQueue的线程中更改UI ...你可以考虑这样的事情:
//...
// show result
final String myResult=result;
SwingUtilities.invokeLater(new Runnable(){
public void run(){
JTF_address.setText(myResult);
}
});