[英]Why does my GUI Send Button freeze when Action Listener is run?
我正在使用帶有與客戶端連接的GUI的聊天服務器
GUI由兩個文本框組成,一個用於接收文本,一個用於發送文本。 最后一件事是發送按鈕,此刻我遇到了問題。
當按下發送按鈕並且不發送消息時,發送按鈕將凍結(GUI仍然起作用,只有它凍結的按鈕)。
我不確定在這里做什么,希望你們能幫助我。 任何幫助表示贊賞,謝謝!
碼:
class UdpServer
{
PrintWriter out;
ButtonHandler txButtonHandler;
BufferedReader in;
DatagramSocket socket;
InetAddress ip = null;
int port;
UdpServer (String gport) throws IOException
{
int i = 0;
socket = new DatagramSocket (Integer.parseInt (gport));
txButtonHandler = new ButtonHandler ();
sendButton.addActionListener (txButtonHandler);
new Thread ()
{
public void run ()
{
try
{
rx ();
}
catch (IOException e)
{
}
}
}.start ();
tx ();
System.exit (1);
}
void tx () throws IOException
{
byte[] buf = new byte[256];
BufferedReader in = new BufferedReader (new InputStreamReader(System.in));
String toServer;
do
{
toServer = in.readLine();
toServer = toServer + "\n";
buf = toServer.getBytes ();
DatagramPacket packet = new DatagramPacket (buf, toServer.length(), ip, port);
if (ip != null) socket.send(packet);
}
while (toServer != null);
socket.close ();
System.exit (1);
}
private class ButtonHandler implements ActionListener
{
public void actionPerformed (ActionEvent event) //throws IOException
{
try{tx ();} catch (IOException e){}
}
}
void rx () throws IOException
{
byte[] buf = new byte[256];
String fromServer;
do
{
for (int i = 0; i < 256; i ++) buf[i] = 0;
DatagramPacket packet = new DatagramPacket (buf, buf.length);
socket.receive (packet);
fromServer = new String (packet.getData());
ip = packet.getAddress ();
port = packet.getPort ();
//System.out.println (port + ":" + ip);
if (fromServer != null) System.out.print (fromServer);
}
while (fromServer != null);
socket.close ();
System.exit (1);
}
}
Swing具有負責更改GUI的特殊線程。 事件調度線程。 來自ActionListeners的方法是在此Thread上執行的,這意味着如果它們花費很長時間,則UI凍結。 因此,您必須在自己的線程中完成工作。 不幸的是,如果您在自己的線程中,並且想要更改UI,則必須在事件分發線程中執行此操作。 您可以使用SwingUtilities.invokeLater做到這一點。
這是一個例子:
import javax.swing.*;
public class Example extends JFrame {
public static void main(String[] args) {
Example example = new Example();
example.setSize(200, 200);
JButton button = new JButton("Do it");
JTextField textField = new JTextField();
button.addActionListener(e ->
new Thread(() -> {
doLongTask();
SwingUtilities.invokeLater(() -> textField.setText("Did it"));
}).start());
example.add(button);
example.add(textField);
example.pack();
example.setVisible(true);
example.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private static void doLongTask() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.