无效的线程访问

时间:2015-02-23 10:18:22

标签: java eclipse multithreading swt eclipse-rcp

创建视图控件类

public void createPartControl(Composite parent) {
        //viewer = new TableViewer(parent, SWT.MULTI| SWT.V_SCROLL);
        //viewer.setContentProvider(new ViewContentProvider());
        //viewer.setLabelProvider(new ViewLabelProvider());
        // Provide the input to the ContentProvider
        //viewer.setInput(new String[] {"One", "Two", "Three"});
        //Display display=new Display();
        parent.getShell().setText("A dialog box with no buttons at all press 'ESC' to close");
        final Shell shell = new Shell(Display.getCurrent());
        new Thread(new Runnable()
        {
            public void run()
            {
                while(true)
                {
                    try
                    {
                        Thread.sleep(1000);
                    }
                    catch(Exception e)
                    {

                    }
                    Display.getDefault().asyncExec(new Runnable()
                    {
                        public void run()
                        {
                            shell.addPaintListener(new PaintListener() {
                                @Override
                                public void paintControl(PaintEvent event) {
                                    Rectangle rect = shell.getClientArea();
                                    event.gc.drawOval(0, 0, rect.width - 1, rect.height - 1);
                                }
                            });
                            Rectangle clientArea = shell.getClientArea();
                            shell.setBounds(clientArea.x + 10, clientArea.y + 10, 200, 200);
                            shell.open ();
                            while (!shell.isDisposed()) 
                            {
                                if (!Display.getCurrent().readAndDispatch()) 
                                    Display.getCurrent().sleep();
                            }
                            Display.getCurrent().dispose();

                        }
                    });
                }
            }

        }).start();
}

任何人都可以解释线程如何在SWT图形中起作用。它表示无效的线程访问。据我说,有一个线程正在运行,我正在创建另一个线程,这绝对是错误的。所以什么是正确的方法。在哪个行中创建默认线程。
它还给出了一个小部件处理错误。为什么?

以下代码是从默认视图插件创建的 here
我的目标是在我的视图中创建图表,而不是在单独的对话框中。 我还附上了日志文件。

!ENTRY org.eclipse.osgi 4 0 2015-02-23 12:47:18.520
!MESSAGE Application error
!STACK 1
org.eclipse.swt.SWTException: Invalid thread access
    at org.eclipse.swt.SWT.error(SWT.java:4441)
    at org.eclipse.swt.SWT.error(SWT.java:4356)
    at org.eclipse.swt.SWT.error(SWT.java:4327)
    at org.eclipse.swt.widgets.Display.error(Display.java:1258)
    at org.eclipse.swt.widgets.Display.checkDevice(Display.java:764)
    at org.eclipse.swt.widgets.Display.removeFilter(Display.java:4065)
    at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.cleanUp(PartRenderingEngine.java:1241)
    at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$5(PartRenderingEngine.java:1237)
    at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1166)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
    at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1032)
    at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:148)
    at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:636)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
    at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:579)
    at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150)
    at swtdiagrams.Application.start(Application.java:20)
    at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:382)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:236)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:648)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:603)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1465)
    at org.eclipse.equinox.launcher.Main.main(Main.java:1438)

!ENTRY org.eclipse.ui.workbench 4 2 2015-02-23 12:47:18.535
!MESSAGE Problems occurred when invoking code from plug-in: "org.eclipse.ui.workbench".
!STACK 0
org.eclipse.swt.SWTException: Widget is disposed
    at org.eclipse.swt.SWT.error(SWT.java:4441)
    at org.eclipse.swt.SWT.error(SWT.java:4356)
    at org.eclipse.swt.SWT.error(SWT.java:4327)
    at org.eclipse.swt.widgets.Display.error(Display.java:1258)
    at org.eclipse.swt.widgets.Display.checkDevice(Display.java:745)
    at org.eclipse.swt.widgets.Display.getActiveShell(Display.java:1469)
    at org.eclipse.ui.internal.services.WorkbenchSourceProvider.getActiveWindow(WorkbenchSourceProvider.java:446)
    at org.eclipse.ui.internal.services.WorkbenchSourceProvider.updateActivePart(WorkbenchSourceProvider.java:478)
    at org.eclipse.ui.internal.services.WorkbenchSourceProvider.checkActivePart(WorkbenchSourceProvider.java:316)
    at org.eclipse.ui.internal.services.WorkbenchSourceProvider.checkActivePart(WorkbenchSourceProvider.java:311)
    at org.eclipse.ui.internal.services.WorkbenchSourceProvider$1.partDeactivated(WorkbenchSourceProvider.java:256)
    at org.eclipse.ui.internal.PartService$4.run(PartService.java:123)
    at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
    at org.eclipse.ui.internal.PartService.partDeactivated(PartService.java:120)
    at org.eclipse.ui.internal.WorkbenchPage$17.run(WorkbenchPage.java:4823)
    at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
    at org.eclipse.ui.internal.WorkbenchPage.firePartDeactivated(WorkbenchPage.java:4820)
    at org.eclipse.ui.internal.WorkbenchPage.access$20(WorkbenchPage.java:4813)
    at org.eclipse.ui.internal.WorkbenchPage$E4PartListener.partDeactivated(WorkbenchPage.java:214)
    at org.eclipse.e4.ui.internal.workbench.PartServiceImpl$4.run(PartServiceImpl.java:250)
    at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
    at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.firePartDeactivated(PartServiceImpl.java:247)
    at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.activate(PartServiceImpl.java:619)
    at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.setPart(PartServiceImpl.java:205)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55)
    at org.eclipse.e4.core.internal.contexts.ContextObjectSupplier$ContextInjectionListener.update(ContextObjectSupplier.java:88)
    at org.eclipse.e4.core.internal.contexts.TrackableComputationExt.update(TrackableComputationExt.java:107)
    at org.eclipse.e4.core.internal.contexts.EclipseContext.processScheduled(EclipseContext.java:338)
    at org.eclipse.e4.core.internal.contexts.EclipseContext.set(EclipseContext.java:352)
    at org.eclipse.e4.core.internal.contexts.EclipseContext.dispose(EclipseContext.java:196)
    at org.eclipse.e4.core.internal.contexts.EclipseContext.dispose(EclipseContext.java:160)
    at org.eclipse.e4.core.internal.contexts.EclipseContext.dispose(EclipseContext.java:160)
    at org.eclipse.e4.core.internal.contexts.EclipseContext.dispose(EclipseContext.java:160)
    at org.eclipse.e4.core.internal.contexts.EclipseContext.dispose(EclipseContext.java:160)
    at org.eclipse.e4.core.internal.contexts.osgi.EclipseContextOSGi.dispose(EclipseContextOSGi.java:103)
    at org.eclipse.e4.core.internal.contexts.osgi.EclipseContextOSGi.bundleChanged(EclipseContextOSGi.java:134)
    at org.eclipse.osgi.internal.framework.BundleContextImpl.dispatchEvent(BundleContextImpl.java:902)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
    at org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEventPrivileged(EquinoxEventPublisher.java:165)
    at org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEvent(EquinoxEventPublisher.java:75)
    at org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEvent(EquinoxEventPublisher.java:67)
    at org.eclipse.osgi.internal.framework.EquinoxContainerAdaptor.publishModuleEvent(EquinoxContainerAdaptor.java:102)
    at org.eclipse.osgi.container.Module.publishEvent(Module.java:466)
    at org.eclipse.osgi.container.Module.doStop(Module.java:624)
    at org.eclipse.osgi.container.Module.stop(Module.java:488)
    at org.eclipse.osgi.container.SystemModule.stop(SystemModule.java:186)
    at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule$1.run(EquinoxBundle.java:160)
    at java.lang.Thread.run(Unknown Source)

我在同样的问题上研究了很多Stackoverflow页面,但没有一个问题与我相似(他们从不想在视图上创建图表)。无论您看到什么代码,都是所有SO建议的结果。许多人甚至没有回答只是评论。
请帮忙。

修改的 在格雷格告诉我编辑后,我得到了。 this

无论如何我可以在视图上打印它(通过视图我的意思是空白而不是它旁边。) 谢谢。

1 个答案:

答案 0 :(得分:2)

您正在dispose()对象上调用Display - 永远不要在Eclipse插件中执行此操作。

如果你想在视图区域中绘制,只需使用Canvas控件,如:

public void createPartControl(Composite parent)
{
  // Create control

  final Canvas canvas = new Canvas(parent, SWT.NONE);

  // Set up a single paint listener

  canvas.addPaintListener(... paint the canvas );

  // Schedule a redraw after 1000 milliseconds

  Display.getCurrent().timerExec(1000, new Runnable() {
     public void run()
     {
       if (!canvas.isDisposed())
        {
          canvas.redraw();

          Display.getCurrent().timerExec(1000, this);
        }
     }
  });     
}