我有两个类,其中一个是我的线程,我通过TCP / IP读取设备的输出:
public static controlPanel cp = new controlPanel();
void startListenForTCP (final String ipaddress){
Thread TCPListenerThread;
TCPListenerThread = new Thread(new Runnable() {
@Override
public void run() {
Boolean run = true;
String serverMessage = null;
InetAddress serverAddr = null;
BufferedWriter out = null;
try
(Socket clientSocket = new Socket(ipaddress, 7420)) {
cp.updateGUI("Connection initiated... waiting for outputs!"+"\n");
char[] buffer = new char[2];
int charsRead = 0;
out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
while ((charsRead = in.read(buffer)) != -1)
{
String message = new String(buffer).substring(0, charsRead);
switch (message) {
case "o,":
cp.updateGUI("Čekanje da loptica prođe RFID čitač!");
break;
case "y,":
cp.updateGUI("Hardverski problem!");
break;
case "Y,":
cp.updateGUI("Loptica nije izažla, hardverski problem!");
break;
case "I,":
cp.updateGUI("Uređaj u stanju mirovanja!!");
break;
default:
String m = message;
m = m.replaceAll("[^\\d.]", "");
try{
int i = Integer.parseInt(m);
System.out.println("Is int: "+i);
int izasao=Integer.parseInt(m);
if (redni>34){
redni=0;
}
if (izasao>0 && izasao<49){
redni =redni+1;
m=m;
ur.updateResults(redni, m);
bs.testAuto(m, redni);
System.out.println(m+ "\n");
}
} catch(NumberFormatException e){
} break;
}
}}
catch(UnknownHostException e) {
System.out.println("Unknown host..."+"\n");
} catch(IOException e) {
System.out.println("IO Error..."+"\n");
}
}
});
TCPListenerThread.start();
}
另一个是swing形式,我想在上面的类中设置jLabel文本:
Public class controlPanel extends javax.swing.JFrame {
public static gameControler gc = new gameControler();
public controlPanel() {
initComponents();
}
public void updateGUI(final String text) {
if (!SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
updateGUI(text);
}
});
}jLabel5.setText(text);
System.out.println(text);
}
消息在控制台中打印出来但我无法将其值设置为jLabel。
我需要一种快速实现此目的的方法,因此任何变通方法都将是最有帮助的。
谢谢,
答案 0 :(得分:3)
如果当前主题不 EDT:
,则您的代码仅更新GUIif (!SwingUtilities.isEventDispatchThread()) {
// you call SwingUtilities.invokeLater();
}
如果当前线程碰巧是EDT,也会发生GUI更新。所以你应该把它改成像这样的东西:
if (SwingUtilities.isEventDispatchThread())
jLabel5.setText(text);
else
SwingUtilities.invokeLater(new Runnable() {
@Override public void run() {
jLabel5.setText(text);
}
});
请注意,invokeLater()
不会立即执行,而是在某个时间以后异步执行。如果您需要在返回之前进行更新,请使用SwingUtilities.invokeAndWait()
。
另请注意,您可以考虑使用SwingWorker
类在后台线程中执行冗长的GUI交互任务。
如果你必须多次这样做,为此制作一个实用的方法是有利可图的:
public void callFromEdt(Runnable task) {
if (SwingUtilities.isEventDispatchThread())
task.run();
else
SwingUtilities.invokeLater(task); // You might want to consider
// using invokeAndWait() instead
}