FORTUNE

          THE WAY TO THE MASTER...
          posts - 49, comments - 18, trackbacks - 0, articles - 1
            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          SWT作為JAVA開(kāi)源世界的優(yōu)秀圖形庫(kù),已經(jīng)得到了很多java愛(ài)好者的青睞。我最近也在使用swt開(kāi)發(fā)一些應(yīng)用程序。我發(fā)現(xiàn)多線程中使用swt需要額外的技巧。

          情形:
              單擊一個(gè)按鈕,然后新開(kāi)一個(gè)線程來(lái)執(zhí)行一個(gè)復(fù)雜的任務(wù)。任務(wù)執(zhí)行完時(shí),彈出一個(gè)對(duì)話框提示任務(wù)執(zhí)行完畢。

          示例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按鈕后會(huì)有異常:
          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)

          為什么會(huì)有異常?沒(méi)有參考書,沒(méi)有人指導(dǎo),你是就此罷休呢,還是刨根問(wèn)底?我想知道答案,那我該怎么做呢?
          請(qǐng)注意,swt是開(kāi)源的,代碼就是你最好的參考書,最好的指導(dǎo)老師!

          查看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 ()”。顯然,在我們的示例中他們是不相等的。因?yàn)椋琈essageBox處在新創(chuàng)建的線程中,而display

          則處在main線程中。可見(jiàn)我們需要在新線程中創(chuàng)建一個(gè)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
                          }
                  }
          }


          好了,程序正常了!

          主站蜘蛛池模板: 共和县| 古浪县| 台安县| 定州市| 棋牌| 泸溪县| 纳雍县| 吉木萨尔县| 斗六市| 芦溪县| 万安县| 台州市| 宝应县| 彰武县| 昌黎县| 宁晋县| 财经| 安塞县| 阿合奇县| 中西区| 罗定市| 万州区| 乌兰浩特市| 慈溪市| 普定县| 武宁县| 隆林| 鹿邑县| 宁陕县| 大余县| 邛崃市| 霞浦县| 布拖县| 鸡泽县| 淮南市| 寿光市| 惠东县| 望城县| 志丹县| 乡城县| 威信县|