在我的Java应用程序中,当调用主模块时,我在一个单独的线程中启动我的SWT GUI.我需要在主线程中执行一些长操作并更新GUI线程.当我尝试从主线程更新GUI线程,即更改标签文本或其他东西时,我得到一个java.lang.NullPointerException.从我在网上看到的是因为SWT不允许非UI线程更新UI对象.如何从主线程更新GUI线程.
我在网上找到了一些例子,但它们都涉及GUI在主线程中运行的情况,而长操作则在单独的线程中.我的情况完全相反.
有人能告诉我如何更新GUI线程中的小部件吗?
Rid*_*del 33
简而言之,SWT是一个单线程UI工具包.因此,必须在SWT事件线程中更新窗口小部件,就像在Swing中一样.因此,您必须使用匿名Runnable类调用刷新:
Display.getDefault().asyncExec(new Runnable() {
public void run() {
someSwtLabel.setText("Complete!");
}
});
Run Code Online (Sandbox Code Playgroud)
对于更长的解释,这篇JavaLobby文章是对这种线程使用模型的一个很好的介绍.
我认为你得到的java.lang.NullPointerException是因为你在创建之前尝试访问GUI组件.理想情况下,您应该等待gui组件被创建...例如......
我在一个单独的线程中创建一个GUI ...就像这样
package test;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
public class GUIThread implements Runnable
{
private Display display;
private Label label;
public Display getDisplay(){
return display;
}
public void run()
{
display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new GridLayout());
shell.setLayoutData(new GridData(SWT.FILL,SWT.FILL,true,false));
label = new Label(shell,SWT.NONE);
label.setText(" -- ");
shell.open();
shell.pack();
while (!shell.isDisposed()) {
if (!display.readAndDispatch ()) display.sleep ();
}
display.dispose();
}
public synchronized void update(final int value)
{
if (display == null || display.isDisposed())
return;
display.asyncExec(new Runnable() {
public void run() {
label.setText(""+value);
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
在我的主要方法中,我做这样的事......
package test;
import org.eclipse.swt.widgets.Display;
public class Main
{
public static void main(String[] args) throws Exception
{
final GUIThread gui = new GUIThread();
Thread t = new Thread(gui);
t.start();
Thread.sleep(3000); // POINT OF FOCUS
Display d = gui.getDisplay();
for(int i = 0; i<100; i++)
{
System.out.println(i + " " + d);
gui.update(i);
Thread.sleep(500);
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我们POINT OF FOCUS在上面的代码中注释掉,那么我将永远得到NullPointerException...但延迟3秒使我的GUI线程有足够的时间处于就绪状态,因此它不会通过NullPointerException.....
在这样的场景中你必须有效地使用wait和yield方法...否则会导致"难以找到错误"...即等待UI正确实例化然后产生...
实际处理也在主线程中完成,GUI在单独的线程中运行...正确通信最好有一些共享和同步的数据结构...或者可以使用套接字通信来完成...你的主线程填充一些port和你的GUI线程asynchronously监听该端口....
希望这会通过你的问题的一些亮点....
| 归档时间: |
|
| 查看次数: |
24408 次 |
| 最近记录: |