2013-11-25 92 views
5

我正在研究此Composite畫布,其他Composite可能會被添加和刪除。SWT Shell根據兒童調整大小

我對整個佈局概念如何仍然迷霧的理解。

當孩子們被添加到容器中時,鑑於容器有填充父母的GridData這一事實,父母是否也應該知道孩子調整了大小?由於殼(頂級父母),兒童在放好容器後仍然隱藏起來。

如果問題太模糊,請不要猶豫,以瞭解更多詳情。另外,請儘量不要將我指向瞭解SWT文章中的佈局。

/** 
* 
* @author ggrec 
* 
*/ 
public class SSCCE 
{ 

    // ==================== 2. Instance Fields ============================ 

    private Composite componentContainer; 

    private int componentCount = 0; 

    // ==================== 3. Static Methods ============================= 

    public static void main(final String[] args) 
    { 
     new SSCCE(); 
    } 

    // ==================== 4. Constructors =============================== 

    private SSCCE() 
    { 
     final Display display = new Display(); 
     final Shell shell = new Shell(display); 
     shell.setLayout(new GridLayout(1, false)); 

     createContents(shell); 

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

    // ==================== 5. Creators =================================== 

    private void createContents(final Composite parent) 
    { 
     parent.setLayout(new GridLayout()); 
     parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 

     final Button button = new Button(parent, SWT.PUSH); 
     button.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 
     button.setText("Add New Component"); 

     button.addSelectionListener(new SelectionAdapter() 
     { 
      @Override public void widgetSelected(final SelectionEvent e) 
      { 
       addNewComponent(); 

       componentContainer.layout(); 
      } 
     }); 

     componentContainer = new Composite(parent, SWT.BORDER); 
     componentContainer.setLayout(new GridLayout()); 
     componentContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 
    } 

    // ==================== 6. Action Methods ============================= 

    private void addNewComponent() 
    { 
     final Composite component = new Composite(componentContainer, SWT.BORDER); 
     component.setLayout(new FillLayout()); 
     component.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 

     final Label label = new Label(component, SWT.NONE); 
     label.setText(String.valueOf(componentCount++)); 
    } 
} 

有趣的事實: 這個問題是veeeery相關to this other one, that was posted 9 minutes ago。有人要麼通靈,要麼跟蹤我。

回答

11

爲了讓Shell來調整你需要佈置的一切,重新計算其大小:

shell.layout(true, true); 

final Point newSize = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); 

shell.setSize(newSize); 

您可以與取決於什麼改變了外殼的孩子Composite呼籲layout()脫身。

+0

您的解決方案似乎適用於更復雜的示例。我想知道'shell.setSize(Point)'是否在我的情況下是強制的(它基本上是'pack(true)')。在完成整個事情之後,我會盡快回復你們。 – GGrec

+0

'pack(true)'與我最後兩行完全相同。我從中提取的代碼也會檢查無法用'pack'完成的最小大小。 –

+0

@ greg-449對於JFace組合框是一樣的。我問過一個問題[這裏](http://stackoverflow.com/questions/32561924/how-to-truncate-a-long-name-in-a-jface-combobox)。 –

3

在這裏可能解決您的問題的祕訣是告訴孩子已經調整大小的父母。所以,不,他們不會自動知道它發生了。

解決這一問題的辦法,是調用:

Parent.layout(true)

從SWT API:

public void layout(boolean changed) 

如果接收器有一個佈局,要求佈局打下(即設置接收者的孩子的大小和位置)。如果參數爲true,則佈局不得依賴任何已經緩存的有關直接子項的信息。如果它是錯誤的,那麼佈局可能(可能)優化它正在做的工作,假設從最後一次佈局以來接收者的孩子都沒有改變狀態。如果接收器沒有佈局,則不執行任何操作。

如果由於對佈局的調用而調整了孩子的尺寸,resize事件將調用孩子的佈局。該佈局將通過接收器的窗口小部件樹中的所有子窗口小部件向下級聯,直到遇到未調整大小的子窗口。請注意,由於調整大小的佈局不會刷新任何緩存的信息(與佈局(false)相同)。

注意:佈局與繪畫不同。如果孩子被移動或調整大小以使父母的某個區域暴露,則父母將繪畫。如果沒有孩子受到影響,父母不會畫畫。

 
Parameters: 
    changed - true if the layout must flush its caches, and false otherwise 
Throws: 
    SWTException - 
    ERROR_WIDGET_DISPOSED - if the receiver has been disposed 
    ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver 

所以你的情況,呼籲他們加入將幫助你擺脫複合隨時隨地的父layout()功能。

+0

在另一種情況下,我試着在'Shell'上調用'layout'。當時似乎沒有工作。這是否也適用於'對話框和'嚮導'?如何*高*你必須去調用API? – GGrec

+0

我有一段代碼的副本,我剛纔寫了一些代碼,當我下班回家時,我會打開它,看看有什麼不同。我記得有一些微妙的東西,我不得不一直玩,直到它的工作。其中一個確實在每次製作新的複合材料時都會調用「佈局(真)」,但我會在幾個小時內聯繫!除非我有靈感和記憶,否則它會更快。 – WillBD

+0

好吧,在重新閱讀你的問題和你在底部提到的問題之後,我可能會在這裏感到困惑。主要問題是您無法看到新的動態按鈕?或者在你製作太多的外殼後整個外殼不會調整大小? – WillBD

0

正如你所說我們兩個問題是相似的,我發佈解決方案,我已經取得了。 讓我知道如果這可以幫助你。

import org.eclipse.jface.dialogs.Dialog; 
import org.eclipse.jface.dialogs.IDialogConstants; 
import org.eclipse.swt.graphics.Point; 
import org.eclipse.swt.widgets.Composite; 
import org.eclipse.swt.widgets.Control; 
import org.eclipse.swt.widgets.Display; 
import org.eclipse.swt.widgets.Shell; 
import org.eclipse.swt.custom.ScrolledComposite; 
import org.eclipse.swt.SWT; 
import org.eclipse.swt.widgets.Label; 
import org.eclipse.swt.layout.GridData; 
import org.eclipse.swt.layout.GridLayout; 
import org.eclipse.swt.layout.FillLayout; 
import org.eclipse.swt.layout.FormLayout; 
import org.eclipse.swt.layout.FormData; 
import org.eclipse.swt.layout.FormAttachment; 
import org.eclipse.swt.widgets.Text; 
import org.eclipse.swt.widgets.Button; 
import org.eclipse.swt.events.SelectionAdapter; 
import org.eclipse.swt.events.SelectionEvent; 
import org.eclipse.swt.widgets.Group; 
import org.eclipse.swt.widgets.Combo; 


public class DynamicDialog extends Dialog { 
    private Composite composite_2; 


    /** 
    * Create the dialog. 
    * @param parentShell 
    */ 
    public DynamicDialog(Shell parentShell) { 
     super(parentShell); 
    } 

    /** 
    * Create contents of the dialog. 
    * @param parent 
    */ 
    @Override 
    protected Control createDialogArea(Composite parent) { 
     Composite container = (Composite) super.createDialogArea(parent); 
     container.setLayout(new FillLayout(SWT.HORIZONTAL)); 

     ScrolledComposite scrolledComposite = new ScrolledComposite(container, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); 
     scrolledComposite.setExpandHorizontal(true); 
     scrolledComposite.setExpandVertical(true); 

     final Composite composite = new Composite(scrolledComposite, SWT.NONE); 
     composite.setLayout(new GridLayout(1, false)); 
     scrolledComposite.setContent(composite); 
     scrolledComposite.setSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); 

     Composite composite_1 = new Composite(composite, SWT.NONE); 
     composite_1.setLayout(new GridLayout(2, false)); 
     GridData gd_composite_1 = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1); 
     gd_composite_1.heightHint = 49; 
     gd_composite_1.widthHint = 427; 
     composite_1.setLayoutData(gd_composite_1); 

     Label lblDefault = new Label(composite_1, SWT.NONE); 
     lblDefault.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); 
     lblDefault.setText("Default:"); 

     Combo combo = new Combo(composite_1, SWT.NONE); 
     combo.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1)); 

     composite_2 = new Composite(composite, SWT.NONE); 
     composite_2.setLayout(new GridLayout(4, false)); 
     GridData gd_composite_2 = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1); 
     /*gd_composite_2.heightHint = 32; 
     gd_composite_2.widthHint = 426;*/ 
     composite_2.setLayoutData(gd_composite_2); 

     Composite composite_3 = new Composite(composite, SWT.NONE); 
     composite_3.setLayout(new GridLayout(1, false)); 
     GridData gd_composite_3 = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1); 
     gd_composite_3.heightHint = 38; 
     gd_composite_3.widthHint = 427; 
     composite_3.setLayoutData(gd_composite_3); 

     Button btnAdd = new Button(composite_3, SWT.NONE); 
     btnAdd.setText("Add"); 
     btnAdd.addSelectionListener(new SelectionAdapter() { 
      @Override 
      public void widgetSelected(SelectionEvent e) { 


       Label label2 = new Label(composite_2, SWT.NONE); 
       label2.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, 
         false, 1, 1)); 
       label2.setText("1"); 

       Text text_12 = new Text(composite_2, SWT.BORDER); 
       text_12.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, 
         false, 1, 1)); 

       Text text13 = new Text(composite_2, SWT.BORDER); 
       text13.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, 
         false, 1, 1)); 

       Button btnDelete = new Button(composite_2, SWT.NONE); 
       btnDelete.setText("delete"); 
       composite_2.layout(true); 


       composite_2.layout(); 
       // Point p = composite.getSize(); 
       // composite.setSize(SWT.DEFAULT,SWT.DEFAULT); 
       // composite.setSize(p); 

       composite.layout(); 


      } 
     }); 






     return container; 
    } 

    /** 
    * Create contents of the button bar. 
    * @param parent 
    */ 
    @Override 
    protected void createButtonsForButtonBar(Composite parent) { 
     createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, 
       true); 
     createButton(parent, IDialogConstants.CANCEL_ID, 
       IDialogConstants.CANCEL_LABEL, false); 
    } 

    /** 
    * Return the initial size of the dialog. 
    */ 
    @Override 
    protected Point getInitialSize() { 
     return new Point(450, 300); 
    } 

public static void main(String[] args){ 

    Shell shell = new Shell(new Display()); 
    //shell.setLayout(new FillLayout()); 
    DynamicDialog dd = new DynamicDialog(shell); 
    dd.open(); 

} 
} 
+0

顯然這解決了你的問題,但不是我的。看到的東西是......當你添加到很多時,他們往往會脫離屏幕,並且你不能手動調整對話框來查看它們。對話框應該自動調整大小 - >查看其他2個答案。 :-) – GGrec

+0

@GGrec是的,現在這是我的問題,每當我在組合中創建新的小部件時,當它到達默認大小的末尾時,它就會進入對話框並且不會出現滾動條。你知道如何解決這個問題,因爲我不太瞭解上述解決方案嗎? , 謝謝 – Juseeth

相關問題