【问题标题】:SWT Invalid Thread Access- Mixing up Displays Draw2DSWT 无效的线程访问 - 混合显示 Draw2D
【发布时间】:2014-07-29 17:18:34
【问题描述】:

我有一个使用 Zest 显示图形的类,它可以独立运行,因为它有一个 main 方法。但是,当我在另一个 shell 中选择一个按钮时,我想运行那个 main 方法。问题是当我从按钮的 selectionListener 调用主函数时,我得到了一个 Invalid Thread Access SWTException 。据我了解,在这两种情况下使用的 Display 对象都会造成麻烦。在这里查看类似的帖子也对我没有帮助..有人可以指出我正确的方向吗?谢谢。 *我添加了简短的可测试代码来说明我的问题。 导入 org.eclipse.swt.widgets.Display;

public class CallGraph {

    protected Shell shell;

    /**
     * Launch the application.
     * @param args
     */
    public static void main(String[] args) {
        try {
            CallGraph window = new CallGraph();
            window.open();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Open the window.
     */
    public void open() {
        Display display = Display.getDefault();
        createContents();
        shell.open();
        shell.layout();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
    }

    /**
     * Create contents of the window.
     */
    protected void createContents() {
        shell = new Shell();
        shell.setSize(450, 300);
        shell.setText("SWT Application");
        shell.setLayout(new GridLayout(6, false));
        new Label(shell, SWT.NONE);
        new Label(shell, SWT.NONE);
        new Label(shell, SWT.NONE);
        new Label(shell, SWT.NONE);
        new Label(shell, SWT.NONE);
        new Label(shell, SWT.NONE);
        new Label(shell, SWT.NONE);
        new Label(shell, SWT.NONE);
        new Label(shell, SWT.NONE);
        new Label(shell, SWT.NONE);
        new Label(shell, SWT.NONE);
        new Label(shell, SWT.NONE);
        new Label(shell, SWT.NONE);
        new Label(shell, SWT.NONE);
        new Label(shell, SWT.NONE);
        new Label(shell, SWT.NONE);
        new Label(shell, SWT.NONE);

        Button btnGetGraph = new Button(shell, SWT.NONE);
        btnGetGraph.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                RadialLayoutExample.main(null);
            }
        });
        btnGetGraph.setText("Get Graph");

    }

}

下面的类有调用上面类的main方法的按钮。

import org.eclipse.swt.SWT;


import org.eclipse.swt.layout.FillLayout;

import org.eclipse.swt.widgets.Display;

import org.eclipse.swt.widgets.Shell;

import org.eclipse.zest.core.widgets.Graph;

import org.eclipse.zest.core.widgets.GraphConnection;

import org.eclipse.zest.core.widgets.GraphNode;

//import org.eclipse.zest.layout.algorithms.RadialLayoutAlgorithm;

//import org.eclipse.zest.layout.interfaces.LayoutAlgorithm;



public class RadialLayoutExample {

        public static void main(String[] args) {

                // Create the shell

                Display d = new Display();

                Shell shell = new Shell(d);

                shell.setText("GraphSnippet1");

                shell.setLayout(new FillLayout());

                shell.setSize(500, 500);



                final Graph g = new Graph(shell, SWT.NONE);

                g.setSize(500, 500);

                GraphNode root = new GraphNode(g, SWT.NONE, "Root");

                for (int i = 0; i < 3; i++) {

                        GraphNode n = new GraphNode(g, SWT.NONE, "1 - " + i);

                        for (int j = 0; j < 3; j++) {

                                GraphNode n2 = new GraphNode(g, SWT.NONE, "2 - " + j);

                                new GraphConnection(g, SWT.NONE, n, n2).setWeight(-1);

                        }

                        new GraphConnection(g, SWT.NONE, root, n);





                //final org.eclipse.zest.layouts.algorithms.RadialLayoutAlgorithm layoutAlgorithm = new org.eclipse.zest.layouts.algorithms.RadialLayoutAlgorithm();
                final org.eclipse.zest.layouts.algorithms.TreeLayoutAlgorithm layoutAlgorithm = new org.eclipse.zest.layouts.algorithms.TreeLayoutAlgorithm();


                g.setLayoutAlgorithm(layoutAlgorithm, true);

                shell.open();

                while (!shell.isDisposed()) {

                        while (!d.readAndDispatch()) {

                                d.sleep();

                        }

                }

        }

}
}

【问题讨论】:

  • 你应该只使用一个Display,你的RadialLayoutExample.main正在创建第二个Display

标签: java multithreading user-interface swt draw2d


【解决方案1】:

将main方法接收到的参数的数据类型从String改为Display。调用 main 方法时,将现有类的显示作为参数传递。这背后的原因是,对于每个应用程序,只需要一个 Display 对象,因为它充当应用程序和底层操作系统之间的链接。与所涉及的线程创建多个混乱。 * 感谢@greg-449 的评论为我指明了正确的方向。

【讨论】:

    猜你喜欢
    • 2011-09-06
    • 2018-04-11
    • 1970-01-01
    • 2011-12-15
    • 1970-01-01
    • 2015-04-24
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    相关资源
    最近更新 更多