【问题标题】:Vertical alignment of label with first row of adjacent control标签与相邻控件的第一行垂直对齐
【发布时间】:2015-10-20 20:02:22
【问题描述】:

如何将标签与相邻 Composite 第一行中的 Combo 垂直对齐?

标签和多行控件与其他控件在 GridLayout 中,标签和字段左对齐。多行控件在其他地方重复使用。

理想情况下,标签中文本的基线和 Combo 应该对齐。在实践中,当 label 和 combo 是兄弟时,使用 SWT.CENTER 将两者垂直居中通常就足够了。

由于字体和外观的差异,我不能只将标签降低编译时常量。

我想到的想法包括:

  • 在运行时,在构建控件时,以某种方式向 Eclipse 询问其组合小部件的高度。将标签嵌入到 Composite 中并适当地填充或对齐。
  • 将标签(可能嵌入在 Composite 中)与从未显示的虚拟 Combo 一起放入 StackLayout 中,以使标签单元格具有同级控件中第一行的高度。将标签在其父级中居中对齐。

有没有更简单/更干净的方法?

【问题讨论】:

  • 在其他使用堆叠组合框组件的地方,你是否也重复使用了标签?
  • 即使您获得了 Combo 的高度,您也不知道文本在控件中的哪个位置,这使得标签文本无法对齐。
  • @luksch - 到目前为止,它只是一个标准的 SWT 标签,除此之外唯一可能重复使用的部分就是名称。但我明白你的意思。如果它不只是一个标准的 SWT 标签,那么有一个单一的定义可能会有好处。
  • @greg-449 - 没错,我不能保证基线会对齐。但是,在实践中,将标签和组合垂直居中往往在可用选项中效果最佳,而且看起来也不错。
  • 实际上在 Mac 上,标签看起来更好,至少对于只读组合而言,底部对齐,读/写组合看起来完全不同。

标签: java layout swt eclipse-rcp


【解决方案1】:

我确认问题可以通过我在问题中建议的第二种方法解决。 如果有人有更好的答案,请发表。

这种方法有这些对象:

AbstractLabelWithHeightOfAnotherControl / custom StackLayout
    <>-- Other control 
         Composite / GridLayout
            <>-- Label / GridData( SWT.BEGINNING, SWT.CENTER, false, true )

自定义 StackLayout 具有标签的宽度,但具有其他控件的高度。

此代码提供了一个抽象类,它支持各种其他控件的行为。

public abstract class AbstractLabelWithHeightOfAnotherControl extends Composite {

private Label m_label;
private Control m_otherControl;

/** Constructor.
 * @param parent
 * @param style
 */
public AbstractLabelWithHeightOfAnotherControl(Composite parent, int style) {
    super( parent, style );

    StackLayout stackLayout = new MyStackLayout();
    this.setLayout( stackLayout );

    Composite layerLabel = new Composite( this, SWT.NONE );
    GridLayout layerLabelLayout = new GridLayout( 1, false );
    layerLabelLayout.marginWidth = 0;
    layerLabelLayout.marginHeight = 0;
    layerLabel.setLayout( layerLabelLayout );
    m_label = new Label( layerLabel, SWT.NONE);
    m_label.setLayoutData( new GridData( SWT.BEGINNING, SWT.CENTER, false, true ) );

    m_otherControl = makeOtherControl( this );

    stackLayout.topControl = layerLabel;
}

protected abstract Control makeOtherControl( @Nonnull Composite parent );

public Label getLabel() {
    return m_label;
}

private final class MyStackLayout extends StackLayout {
    MyStackLayout() {
        this.marginHeight = 0;
        this.marginWidth = 0;
    }

    @Override
    protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
        int width = m_label.computeSize( wHint, hHint, flushCache ).x;
        int height = m_otherControl.computeSize( wHint, hHint, flushCache ).y;

        if (wHint != SWT.DEFAULT) width = wHint;
        if (hHint != SWT.DEFAULT) height = hHint;
        return new Point(width, height);
    }
}
}

实现类可以只提供这样的方法:

@Override
protected Control makeOtherControl( @Nonnull Composite parent ) {
    return new Combo( parent, SWT.NONE );
}

【讨论】:

    【解决方案2】:

    如何创建这样的组件:

    +-------------------------------+ 
    | +---------------------------+ |
    | |  +------+ +-------------+ | |
    | |  |Label | |Combobox     | | |
    | |  +------+ +-------------+ | |
    | +---------------------------+ |
    | |  +------+ +-------------+ | |
    | |  |Dummy | |Combobox     | | |
    | |  +------+ +-------------+ | |
    | +---------------------------+ |
    | |  +------+ +-------------+ | |
    | |  |Dummy | |Combobox     | | |
    | |  +------+ +-------------+ | |
    | +---------------------------+ |
    +-------------------------------+ 
    

    通过将标签文本作为输入的方法创建它。假人是空标签,如果你愿意的话。如果方法标签文本为空,您可以完全省略标签的创建或全部为空。这样您就可以重用带有或不带有标签的多组合框组件。

    【讨论】:

    • 对于我面临的问题,多行控件需要与多行控件的的GridLayout中的其他字段左对齐。并且标签需要与该父级中的其他标签左对齐。使用父级中的标准 GridLayout,标签和多行控件需要放在单独的单元格中。抱歉,我只在文字中表达了这一点,而不是在插图中。
    • 我明白了。那我觉得你的第二种方法还可以,虽然感觉有点麻烦。
    • 我同意,更简单的方法会很好。从好的方面来说,代码并没有那么长。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-08
    • 1970-01-01
    • 1970-01-01
    • 2011-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多