从另一个线程更新SWT对象
在我的Java应用程序中,当调用主模块时,我在一个单独的线程中启动我的SWT GUI。 我需要在主线程中执行一些长操作并更新GUI线程。 当我尝试从主线程更新GUI线程,即更改标签文本或其他东西时,我得到一个java.lang.NullPointerException
。 从我在网上看到的是因为SWT不允许非UI线程更新UI对象。 如何从主线程更新GUI线程。
我在网上找到了一些例子,但它们都处理了GUI在主线程中运行的情况,而长操作则在单独的线程中。 我的情况完全相反。
有人能告诉我如何更新GUI线程中的小部件吗?
我认为您正在获取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); } }); } }
在我的主要方法中,我做这样的事情….
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); } } }
现在,如果我们在上面的代码中注释出POINT OF FOCUS
,那么我将总是得到NullPointerException
......但是3秒的延迟使我的GUI线程有足够的时间处于就绪状态,因此它不会通过NullPointerException
...... ..
在这种情况下你必须有效地使用wait
和yield
方法......否则会导致“难以找到错误”...即等待UI正确实例化然后产生...
实际处理也是在主线程中完成的,GUI在单独的线程中运行...正确通信最好有一些共享和同步的数据结构...或者可以使用套接字通信完成...你的主线程填充一些port
和你的GUI线程asynchronously
监听该端口....
希望这会通过你的问题的一些亮点....
简而言之,SWT是一个单线程UI工具包。 因此,必须在SWT事件线程中更新窗口小部件,就像在Swing中一样。 因此,您必须使用匿名Runnable
类调用刷新:
Display.getDefault().asyncExec(new Runnable() { public void run() { someSwtLabel.setText("Complete!"); } });
对于更长的解释,这篇JavaLobby文章是对这种线程使用模型的一个很好的介绍。
- JAXWS和会话
- 头尾递归之间的区别
- 如何处理摆动中图像显示的错误文件选择
- 使用minimax可以使用多少个线程来进行井字游戏?
- 如何在不重新启动Spring启动应用程序的情况下更改运行时的日志级别
- java.lang.NoSuchMethodError:org.slf4j.spi.LocationAwareLogger.log(Lorg / slf4j / Marker; Ljava / lang / String; ILjava / lang / String; [Ljava / lang / Obje
- Nodejs Crypto Javascript中的javax.crypto.Cipher等效代码
- 从Jar加载图像:始终为null
- Method getResources没有用请求类型注释(例如,GET,POST)是什么意思?