2010-08-02 17 views
2

這是一個顯示問題的簡單可執行代碼段。SWT ExpandListener在Linux上發生崩潰之前執行

當使用ExpandBar時,所需的結果是在出現摺疊或展開時調整窗口大小。它在Mac上正常工作,但不在Linux上。

它看起來像ExpandListener之前崩潰/實際展開時,因此包()調整大小不正確被調用。

異步執行僅僅是讓它在Mac上工作的繃帶,但這在Linux上不起作用。

import org.eclipse.swt.*; 
import org.eclipse.swt.layout.*; 
import org.eclipse.swt.widgets.*; 
import org.eclipse.swt.events.ExpandEvent; 
import org.eclipse.swt.events.ExpandListener; 

public class ExpandBarExample { 
    public static void main(String[] args) { 
     Shell shell = new Shell(SWT.DIALOG_TRIM | SWT.MIN 
       | SWT.APPLICATION_MODAL); 
     shell.setLayout(new FormLayout()); 
     shell.setText("Expand Bar"); 
     final ExpandBar bar = new ExpandBar(shell, SWT.NONE); 
     FormData fd = new FormData(); 
     fd.top = new FormAttachment(0); 
     fd.left = new FormAttachment(0); 
     fd.right = new FormAttachment(100); 
     fd.bottom = new FormAttachment(100); 
     bar.setLayoutData(fd); 

     bar.addExpandListener(new ExpandListener() { 

      public void itemCollapsed(ExpandEvent arg0) { 
       Display.getCurrent().asyncExec(new Runnable() { 
        public void run() { 
         bar.getShell().pack(); 
        } 
       }); 
      } 

      public void itemExpanded(ExpandEvent arg0) { 
       bar.getShell().pack(); 

       Display.getCurrent().asyncExec(new Runnable() { 
        public void run() { 
         bar.getShell().pack(); 
        } 
       }); 
      } 

     }); 

     Composite composite = new Composite(bar, SWT.NONE); 
     fd = new FormData(); 
     fd.left = new FormAttachment(0); 
     fd.right = new FormAttachment(100); 
     composite.setLayoutData(fd); 

     FormLayout layout = new FormLayout(); 
     layout.marginLeft = layout.marginTop = layout.marginRight = layout.marginBottom = 8; 

     composite.setLayout(layout); 
     Label label = new Label(composite, SWT.NONE); 
     label.setText("This is Bar 1"); 
     ExpandItem item1 = new ExpandItem(bar, SWT.NONE, 0); 
     item1.setText("Bar 1"); 
     item1.setHeight(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y); 
     item1.setControl(composite); 
     item1.setExpanded(true); 

     composite = new Composite(bar, SWT.NONE); 
     fd = new FormData(); 
     fd.left = new FormAttachment(0); 
     fd.right = new FormAttachment(100); 
     composite.setLayoutData(fd); 

     layout = new FormLayout(); 
     layout.marginLeft = layout.marginTop = layout.marginRight = layout.marginBottom = 8; 
     composite.setLayout(layout); 
     label = new Label(composite, SWT.NONE); 
     label.setText("This is Bar2"); 
     ExpandItem item2 = new ExpandItem(bar, SWT.NONE, 1); 
     item2.setText("Bar 2"); 
     item2.setHeight(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y); 
     item2.setControl(composite); 
     item2.setExpanded(true); 

     composite = new Composite(bar, SWT.NONE); 
     fd = new FormData(); 
     fd.left = new FormAttachment(0); 
     fd.right = new FormAttachment(100); 
     composite.setLayoutData(fd); 

     layout = new FormLayout(); 
     layout.marginLeft = layout.marginTop = layout.marginRight = layout.marginBottom = 8; 
     composite.setLayout(layout); 
     label = new Label(composite, SWT.NONE); 
     label.setText("This is Bar3"); 
     ExpandItem item3 = new ExpandItem(bar, SWT.NONE, 2); 
     item3.setText("Bar 3"); 
     item3.setHeight(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y); 
     item3.setControl(composite); 
     item3.setExpanded(true); 

     bar.setSpacing(6); 
     shell.pack(); 
     shell.open(); 
     Display display = shell.getDisplay(); 

     while (!shell.isDisposed()) { 
      if (!display.readAndDispatch()) { 
       display.sleep(); 
      } 
     } 
     display.dispose(); 
    } 

} 
+0

+50賞金頒發給我自己,不幸的。 – 2010-08-10 00:11:16

回答

2

我對這個解決方案不滿意,但它的工作原理。

絕對是XXX解決方案

使用XXX中標誌的東西是假的,但工作的意見。使用FIXME標記一些虛假和破壞的東西。 - java.sun.com

事不宜遲

import org.eclipse.swt.*; 
import org.eclipse.swt.layout.*; 
import org.eclipse.swt.widgets.*; 
import org.eclipse.swt.events.ExpandEvent; 
import org.eclipse.swt.events.ExpandListener; 

public class ExpandBarExample { 
    public static void main(String[] args) { 
     Shell shell = new Shell(SWT.DIALOG_TRIM | SWT.MIN 
       | SWT.APPLICATION_MODAL); 
     shell.setLayout(new FormLayout()); 
     shell.setText("Expand Bar"); 
     final ExpandBar bar = new ExpandBar(shell, SWT.NONE); 
     FormData fd = new FormData(); 
     fd.top = new FormAttachment(0); 
     fd.left = new FormAttachment(0); 
     fd.right = new FormAttachment(100); 
     fd.bottom = new FormAttachment(100); 
     bar.setLayoutData(fd); 

     bar.addExpandListener(new ExpandListener() { 

      private void resize(final ExpandEvent event, final boolean expand){ 

       final Display display = Display.getCurrent(); 

       new Thread(new Runnable() { 
        public void run() { 

         final int[] orgSize = new int[1]; 
         final int[] currentSize = new int[1]; 

         final Object lock = new Object(); 

         if (display.isDisposed() || bar.isDisposed()){ 
          return; 
         } 

         display.syncExec(new Runnable() { 
          public void run() { 
           if (bar.isDisposed() || bar.getShell().isDisposed()){ 
            return; 
           } 

           synchronized(lock){ 
            bar.getShell().pack(true); 
            orgSize[0] = bar.getShell().getSize().y; 
            currentSize[0] = orgSize[0]; 
           } 
          } 
         });  

         while (currentSize[0] == orgSize[0]){ 
          if (display.isDisposed() || bar.isDisposed()){ 
           return; 
          } 

          display.syncExec(new Runnable() { 
           public void run() { 

            synchronized(lock){ 
             if (bar.isDisposed() || bar.getShell().isDisposed()){ 
              return; 
             } 

             currentSize[0] = bar.getShell().getSize().y; 

             if (currentSize[0] != orgSize[0]){ 
              return; 
             } 
             else{ 
              bar.getShell().layout(true); 
              bar.getShell().pack(true); 
             } 
            } 
           } 
          });        
         } 
        } 
       }).start(); 
     } 

     public void itemCollapsed(ExpandEvent event) { 
      resize(event, false); 
     } 

     public void itemExpanded(ExpandEvent event) {   
      resize(event, true); 
     } 

     }); 

     Composite composite = new Composite(bar, SWT.NONE); 
     fd = new FormData(); 
     fd.left = new FormAttachment(0); 
     fd.right = new FormAttachment(100); 
     composite.setLayoutData(fd); 

     FormLayout layout = new FormLayout(); 
     layout.marginLeft = layout.marginTop = layout.marginRight = layout.marginBottom = 8; 

     composite.setLayout(layout); 
     Label label = new Label(composite, SWT.NONE); 
     label.setText("This is Bar 1"); 
     ExpandItem item1 = new ExpandItem(bar, SWT.NONE, 0); 
     item1.setText("Bar 1"); 
     item1.setHeight(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y); 
     item1.setControl(composite); 
     item1.setExpanded(true); 

     composite = new Composite(bar, SWT.NONE); 
     fd = new FormData(); 
     fd.left = new FormAttachment(0); 
     fd.right = new FormAttachment(100); 
     composite.setLayoutData(fd); 

     layout = new FormLayout(); 
     layout.marginLeft = layout.marginTop = layout.marginRight = layout.marginBottom = 8; 
     composite.setLayout(layout); 
     label = new Label(composite, SWT.NONE); 
     label.setText("This is Bar2"); 
     ExpandItem item2 = new ExpandItem(bar, SWT.NONE, 1); 
     item2.setText("Bar 2"); 
     item2.setHeight(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y); 
     item2.setControl(composite); 
     item2.setExpanded(true); 

     composite = new Composite(bar, SWT.NONE); 
     fd = new FormData(); 
     fd.left = new FormAttachment(0); 
     fd.right = new FormAttachment(100); 
     composite.setLayoutData(fd); 

     layout = new FormLayout(); 
     layout.marginLeft = layout.marginTop = layout.marginRight = layout.marginBottom = 8; 
     composite.setLayout(layout); 
     label = new Label(composite, SWT.NONE); 
     label.setText("This is Bar3"); 
     ExpandItem item3 = new ExpandItem(bar, SWT.NONE, 2); 
     item3.setText("Bar 3"); 
     item3.setHeight(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y); 
     item3.setControl(composite); 
     item3.setExpanded(true); 

     bar.setSpacing(6); 
     shell.pack(); 
     shell.open(); 
     Display display = shell.getDisplay(); 

     while (!shell.isDisposed()) { 
      if (!display.readAndDispatch()) { 
       display.sleep(); 
      } 
     } 
     display.dispose(); 
    } 

} 

如果有人想知道這是什麼做的,不希望看的代碼。

基本上ExpandListener着眼於外殼的原始高度,併發出syncExec對包()殼直到殼實際上改變大小。一個非常繁忙的等待方法。

2

這是一箇舊的帖子,但我最近有這個問題,並發現這個解決方案helphul。

但是,我發現只需要從另一個線程調用shell.pack()(當然是通過syncExec)。我從來不需要經過循環。所以我對這個小子程序進行了處理:

private void async_shell_pack(final Display display, final ExpandBar bar) { 
    new Thread(new Runnable(){ 
     public void run(){ 
      display.syncExec(new Runnable() { 
       public void run() { 
          bar.getShell().pack(true); 
         } 
        }); 
      }}).start(); 
     } 

這似乎工作正常。爲了我的目的,更好的方法是使用下面的監聽器簡單地通過擴展項的高度來增加shell的高度。

public void itemExpanded(ExpandEvent e) { 
     if (e.item instanceof ExpandItem){ 
       ExpandItem item = (ExpandItem)e.item; 
       shell.setSize(shell.getSize().x, shell.getSize().y+item.getHeight()); 
      } else { 
       System.out.println("Boom"); 
      } 
     } 

這意味着不要搞亂線程。