2017-04-20 44 views
1

我想要一個帶有一些標籤的組合,並且所有標籤都應該具有相同的高度,但它們應該垂直居中。使用等高的行創建GridLayout

到目前爲止,我有以下幾點:

public static void main(String[] args) { 
    final Display display = new Display(); 
    final Shell shell = new Shell(display); 
    shell.setLayout(new FillLayout()); 

    final Composite composite = new Composite(shell, SWT.VERTICAL); 
    composite.setLayout(GridLayoutFactory.fillDefaults().numColumns(1).equalWidth(true).spacing(0, 0).create()); 
    for (int i = 0; i < 10; i++) { 
     final Label label = new Label(composite, SWT.WRAP); 
     label.setAlignment(SWT.CENTER); 
     label.setText(i < 5 ? "small " + i : "a very big text for the row that is named " + i); 
     label.setToolTipText(label.getText()); 
     label.setLayoutData(GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).grab(true, true).create()); 
    } 

    shell.setSize(100, 600); 
    shell.open(); 

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

正如你所看到的,標籤垂直居中在其列,但那些其包裝需要更多的空間比其他的人。

如果我將hint(SWT.DEFAULT, 60)添加到GridData,我可以強制標籤具有相同的高度,但它們不會再被垂直居中。

我可能會將所有標籤包裹在複合材料中,在複合材料上設置高度提示並將標籤居中,但讓我們先看看另一個選項。

如何創建垂直居中的等高行?

回答

2

由於您試圖統一安排可能不同大小的小部件,因此我認爲一個不錯的選擇是將每個Label放入Composite。這樣每個Composite可以具有相同的大小,並且Label將在其中居中。

通過添加ControlListenerComposite,您可以檢查每個孩子Composite的大小,然後將每個孩子的高度提示是最大的孩子的身高:

public static void main(final String[] args) { 
    final Display display = new Display(); 
    final Shell shell = new Shell(display); 
    shell.setLayout(new FillLayout()); 

    final Composite composite = new Composite(shell, SWT.VERTICAL); 
    composite.setLayout(GridLayoutFactory.fillDefaults().numColumns(1).equalWidth(true).spacing(0, 0).create()); 

    final List<Composite> children = new ArrayList<Composite>(); 
    for (int i = 0; i < 10; i++) { 
     final Composite c = new Composite(composite, SWT.BORDER); 
     c.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 
     c.setLayout(new GridLayout()); 

     final Label label = new Label(c, SWT.WRAP); 
     label.setAlignment(SWT.CENTER); 
     label.setText(i < 5 ? "small " + i : "a very big text for the row that is named " + i); 
     label.setToolTipText(label.getText()); 
     label.setLayoutData(GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).grab(true, true).create()); 

     children.add(c); 
    } 

    composite.addControlListener(new ControlAdapter() { 
     @Override 
     public void controlResized(final ControlEvent e) { 
      int maxHeight = 0; 
      for (final Composite c : children) { 
       if (c.getClientArea().height > maxHeight) { 
        maxHeight = c.getClientArea().height; 
       } 
      } 
      for (final Composite c : children) { 
       ((GridData) c.getLayoutData()).heightHint = maxHeight; 
      } 
     } 
    }); 

    shell.setSize(100, 600); 
    shell.open(); 

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

結果:

enter image description here

和調整後:

enter image description here enter image description here

+0

這似乎只是巧合。 'Composite.getClientArea()。y'是它的y座標,而不是它的高度。您需要執行'getClientArea()。height'或'getSize()。y'。 – mapeters

+0

另外,對於我來說,'getClientArea()。height'和'getSize()。y'總是爲0. – mapeters

+1

@mapeters好的catch - 肯定應該是'getClientArea()。height'。我更新了代碼,謝謝!由getClientArea()返回的'Rectangle'是0x0,直到第一次調整大小。然後它將被正確地計算出來,如果你在'ControlListener'中輸出一個打印語句,你會看到它發生了變化。 – avojak