新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论Java, J2SE, J2ME, J2EE, 以及Eclipse, NetBeans, JBuilder等Java开发环境,还有JSP, JavaServlet, JavaBean, EJB以及struts, hibernate, spring, webwork2, Java 3D, JOGL等相关技术。
    [返回] 计算机科学论坛计算机技术与应用『 Java/Eclipse 』 → SWT和多线程结合使用的问题释疑 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 9441 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: SWT和多线程结合使用的问题释疑 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     jjplion 帅哥哟,离线,有人找我吗?
      
      
      等级:大一(猛啃高等数学)
      文章:15
      积分:116
      门派:XML.ORG.CN
      注册:2005/4/11

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给jjplion发送一个短消息 把jjplion加入好友 查看jjplion的个人资料 搜索jjplion在『 Java/Eclipse 』的所有贴子 引用回复这个贴子 回复这个贴子 查看jjplion的博客楼主
    发贴心情 SWT和多线程结合使用的问题释疑

    SWT和多线程结合使用的问题释疑

    作者:jjp

    SWT作为JAVA开源世界的优秀图形库,已经得到了很多java爱好者的青睐。我最近也在使用swt开发一些应用程序。我发现多线程中使用swt需要额外的技巧。

    情形:
        单击一个按钮,然后新开一个线程来执行一个复杂的任务。任务执行完时,弹出一个对话框提示任务执行完毕。

    示例1:

    package threadandui;

    import org.eclipse.swt.SWT;
    import org.eclipse.swt.widgets.Display;
    import org.eclipse.swt.widgets.MessageBox;
    import org.eclipse.swt.widgets.Shell;
    import org.eclipse.swt.widgets.Button;
    import org.eclipse.swt.events.SelectionAdapter;
    import org.eclipse.swt.events.SelectionEvent;

    public class TestSwt1 extends Shell {
            public static Shell shell;
            public static void main(String args[]) {
                    try {
                            Display display = Display.getDefault();
                            shell = new TestSwt1(display, SWT.SHELL_TRIM);
                            shell.open();
                            shell.layout();
                            while (!shell.isDisposed()) {
                                    if (!display.readAndDispatch())
                                            display.sleep();
                            }
                    } catch (Exception e) {
                            e.printStackTrace();
                    }
            }

            public TestSwt1(Display display, int style) {
                    super(display, style);
                    createContents();
            }

            protected void createContents() {
                    setText("SWT Application1");
                    setSize(500, 375);

                    final Button button = new Button(this, SWT.NONE);
                    button.addSelectionListener(new SelectionAdapter() {
                            public void widgetSelected(SelectionEvent e) {
                                    new MyThread().start();
                            }
                    });
                    button.setBounds(80, 50, 85, 25);
                    button.setText("start");
            }

            protected void checkSubclass() {
            }
            
            class MyThread extends Thread{
                    public void run(){
                            //complex task
    //                        for(int i=0;i < 10000;i++){
    //                                System.out.println(i);
    //                        }
                            //display a dialog                         
                            MessageBox mb = new MessageBox(shell);
                            mb.setMessage("Task ended!");
                            mb.open();
                    }
            }
    }

    该程序在单击start按钮后会有异常:
    Exception in thread "Thread-0" org.eclipse.swt.SWTException: Invalid thread access
            at org.eclipse.swt.SWT.error(SWT.java:2691)
            at org.eclipse.swt.SWT.error(SWT.java:2616)
            at org.eclipse.swt.SWT.error(SWT.java:2587)
            at org.eclipse.swt.widgets.Widget.error(Widget.java:381)
            at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:284)
            at org.eclipse.swt.widgets.Dialog.checkParent(Dialog.java:154)
            at org.eclipse.swt.widgets.Dialog.<init>(Dialog.java:116)
            at org.eclipse.swt.widgets.MessageBox.<init>(MessageBox.java:81)
            at org.eclipse.swt.widgets.MessageBox.<init>(MessageBox.java:54)
            at threadandui.TestSwt1$MyThread.run(TestSwt1.java:70)

    为什么会有异常?没有参考书,没有人指导,你是就此罢休呢,还是刨根问底?我想知道答案,那我该怎么做呢?
    请注意,swt是开源的,代码就是你最好的参考书,最好的指导老师!

    查看swt源代码:at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:284)

    /*245*/        protected void checkWidget () {
            
    /*246*/                Display display = this.display;
            
    /*247*/                if (display == null) error (SWT.ERROR_WIDGET_DISPOSED);
            
    /*248*/                if (display.thread != Thread.currentThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
            
    /*249*/                if ((state & DISPOSED) != 0) error (SWT.ERROR_WIDGET_DISPOSED);

    /*250*/        }
    第248行有判断“display.thread != Thread.currentThread ()”。显然,在我们的示例中他们是不相等的。因为,MessageBox处在新创建的线程中,而display

    则处在main线程中。可见我们需要在新线程中创建一个display给MessageBox使用。“示例2”给出了答案。


    示例2;
    /*
    * Created on 2005-5-26
    *
    * TODO To change the template for this generated file go to
    * Window - Preferences - Java - Code Style - Code Templates
    */
    package threadandui;

    import org.eclipse.swt.SWT;
    import org.eclipse.swt.widgets.Display;
    import org.eclipse.swt.widgets.MessageBox;
    import org.eclipse.swt.widgets.Shell;
    import org.eclipse.swt.widgets.Button;
    import org.eclipse.swt.events.SelectionAdapter;
    import org.eclipse.swt.events.SelectionEvent;

    /**
    * @author jiangjunping
    *
    * TODO To change the template for this generated type comment go to
    * Window - Preferences - Java - Code Style - Code Templates
    */
    public class TestSwt2 extends Shell {
            public static Shell shell;
            public static void main(String args[]) {
                    try {
                            Display display = Display.getDefault();
                            shell = new TestSwt2(display, SWT.SHELL_TRIM);
                            shell.open();
                            shell.layout();
                            while (!shell.isDisposed()) {
                                    if (!display.readAndDispatch())
                                            display.sleep();
                            }
                    } catch (Exception e) {
                            e.printStackTrace();
                    }
            }

            public TestSwt2(Display display, int style) {
                    super(display, style);
                    createContents();
            }

            protected void createContents() {
                    setText("SWT Application2");
                    setSize(500, 375);

                    final Button button = new Button(this, SWT.NONE);
                    button.addSelectionListener(new SelectionAdapter() {
                            public void widgetSelected(SelectionEvent e) {
                                    new MyThread().start();
                            }
                    });
                    button.setBounds(80, 50, 85, 25);
                    button.setText("start");
                    //
            }

            protected void checkSubclass() {
            }
            
            class MyThread extends Thread{
                    public void run(){
                            //complex task
                            for(int i=0;i < 50000;i++){
                                    System.out.println(i);
                            }
                            //display a dialog                         
                            Display display = new Display();//new display
                            Shell shell2 = new Shell(display);//added
                            MessageBox mb = new MessageBox(shell2);//use new display created in the current thread
                            mb.setMessage("Task ended!");
                            mb.open();
                            display.dispose();//added
                    }
            }
    }


    好了,程序正常了!


       收藏   分享  
    顶(0)
      




    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2005/6/18 12:19:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 Java/Eclipse 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/11/20 9:34:43

    本主题贴数1,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    78.125ms