在这种情况下,我应该使用什么类型的消息传递?GUI向线程发送命令;Java



我有一个JFrame,我称之为mainFrame,它是在使用我的程序时向用户显示的主JFrame。

该程序创建一个到服务器的套接字,并在它和服务器之间来回发送消息。

我正在尝试创建一个线程来处理连接。因此,当用户单击"连接"时,线程将设置套接字以及相关的输入和输出流。然后,我希望线程等待,直到JFrame向它发送一个命令,该命令只是一个字符串,它应该打印到Socket的输出流中。线程将发送命令,读取响应,然后等待另一个命令。

我想我可以设置一个队列,我可以将命令"存放"到其中,然后当线程到达它时,它可以从队列中提取第一个命令,并随心所欲地处理它。

有什么办法吗?

此外,目前我将参数this传递给线程,以便它可以访问JFrame中的一个函数,将输出打印到文本区域。这样可以吗?我可以允许线程调用派生它的JFrame中的方法吗?

建议:

  • Swing GUI可以向Socket发送文本,我认为不需要任何额外的线程,因为这是非阻塞的
  • 是的,需要一个单独的线程来等待套接字并读取传入的数据。为此,您可以使用扫描仪或BufferedReader
  • 然后,可能在遇到任何新行字符时,将该线程中的文本发送到GUI。这将需要在EDT上完成,可能通过SwingWorker与PropertyChangeListener的发布/处理方法对
  • 是的,后台线程可以在GUI上调用方法,但始终要注意在Swing事件线程上执行此操作,方法是将代码放在Runnable中,并通过SwingUtilities.invokeLater(...)将其排队到Swing事件队列中

编辑
您的评论:

"在EDT上"是什么意思?

EDT=SwingE通风口DispatchT线程,执行所有Swing绘图和用户交互的主Swing线程。如果你阻塞了这个线程,你就阻塞了Swing的所有显示和UI,基本上冻结了你的程序。有关详细信息,请参阅Swing中的并发。

还说向套接字发送文本是阻塞的,我如何为它设置命令队列?

我不理解这个问题,因为据我所知,在套接字上发送信息不应该是阻塞。

请参阅此代码,但您必须自己实现参数:

public class ConnectionThread extends Thread {
public static final HOST = "www.example.com";
public static final PORT = 24239;
private String command;
private boolean lookahead = false;
private boolean allowChangeLookahead = true;
private boolean canRetrieveResult = false;
Private String result;
orivate Socket s = new Socket(HOST, PORT);
public void run() {
for(;;) { // Infinite loop
sleep(500); // Avoid low perfomance related problems.
if(lookahead) {
allowChangeLookahead = false;
try {
PrintWriter out = new PrintWriter(s.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
out.println(command);
result = in.readLine();
canRetrieveResult = true;
} catch(Exception e) {
// Something occured...
}
lookahead = false;
allowChangeLookAhead = true;
}
}
}
public synchronized void command(String cmd) {
command = cmd;
for(;;) { // Don't worry, not infinite
if(allowChangeLookahead) {
lookahead = true;
break;
}
}
}
public synchronized String getResult() {
for(;;) {
if(canRetrieveResult) {
return result;
}
}
}
}

同时,在主序列中

ConnectionThread conThread = new ConnectionThread();
conThread.start();
// ...
// Code of method that responds to command
if(calledCommand) {
conThread.command(theCommand);
result = conThread.getResult();
}

就这样!记得写服务器,如果你需要帮助,问我

最新更新