我在JFace对话框中有一个SWT Composite。在复合材料的一行中,我有一个垂直堆叠的4个按钮组。它旁边是一个Text小部件,需要通过用户输入在多行和单行之间来回切换。
我在StackLayout中有两个不同的Text小部件,我根据需要显示一个或另一个。但我找不到一种方法来调整Stack Composite和Text小部件的高度,具体取决于哪个Text是顶级控件。在单模式下我只需要一行高度,并且在多模式下填充与它旁边的组相同的垂直空间。当我创建Composite时,我可以将Text的高度调整为这些条件中的任何一个,但是当我从一个Text切换到另一个Text时,他们不会调整它们的高度。
这是一个代码段,导致文本小部件总是太高,在单一模式下永远不会缩小到一行高度。
这是复合
@Override
protected Control createDialogArea(Composite parent) {
container = (Composite) super.createDialogArea(parent);
GridDataFactory.fillDefaults().grab(true, true).applyTo(container);
GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(container);
Group group = new Group(container, SWT.NONE);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(group);
GridLayoutFactory.fillDefaults().applyTo(group);
for (M_ATTRIBUTE attr : M_ATTRIBUTE.values()) {
Button button = new Button(group, SWT.CHECK);
GridDataFactory.fillDefaults().applyTo(button);
button.setText(attr.getDisplayValue());
}
stack = new Composite(container, SWT.NONE);
GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(stack);
stackLayout = new StackLayout();
stack.setLayout(stackLayout);
valueTextMulti = new Text(stack, SWT.BORDER | SWT.MULTI);
GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(valueTextMulti);
valueTextMulti.addModifyListener(valueTextModifyListener);
valueTextSingle = new Text(stack, SWT.BORDER | SWT.SINGLE);
GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(valueTextSingle);
valueTextSingle.addModifyListener(valueTextModifyListener);
stackLayout.topControl = valueTextMulti;
return container;
}
这里有一个switch语句,显示我在单行和多行Text Widgets之间切换的方法。
@Override
public void selectionChanged(SelectionChangedEvent event) {
IStructuredSelection sel = (IStructuredSelection) event.getSelection();
M_DATA_TYPE type = (M_DATA_TYPE) sel.getFirstElement();
switch (type) {
case LIST:
case HASH_TABLE:
stackLayout.topControl = valueTextMulti;
setNumRows(valueTextMulti, 10);
((GridData) valueTextMulti.getLayoutData()).verticalAlignment = SWT.FILL;
((GridData) valueTextMulti.getLayoutData()).grabExcessVerticalSpace = true;
((GridData) stack.getLayoutData()).grabExcessVerticalSpace = true;
container.getParent().layout();
break;
default:
stackLayout.topControl = valueTextSingle;
((GridData) valueTextSingle.getLayoutData()).verticalAlignment = SWT.TOP;
((GridData) valueTextSingle.getLayoutData()).grabExcessVerticalSpace = false;
((GridData) stack.getLayoutData()).grabExcessVerticalSpace = false;
setNumRows(valueTextSingle, 1);
container.getParent().layout();
break;
}
}
以下是根据another StackOverflow post从字符行调整文本高度的方法。
protected void setNumRows(Text text, int rows) {
GC gc = new GC(text);
try
{
gc.setFont(text.getFont());
FontMetrics fm = gc.getFontMetrics();
int height = rows * fm.getHeight();
text.setSize(text.getSize().x, height);
text.getParent().layout();
}
finally
{
gc.dispose();
}
}
答案 0 :(得分:0)
我通过在StackLayout组合内创建其他组合来实现它,每个Text小部件实例都有一个。每个Text小部件都有固定的布局数据,一个使用align = SWT.FILL,另一个使用SWT.TOP。然后我只是在StackLayout中切换容器组合而不是切换Text小部件。这具有不需要直接设置小部件高度的附加优点。切换内容后,还必须在StackLayout组合上调用layout()。在层次结构中较高的容器上调用layout()不起作用。
这是我修改后的代码:
@Override
protected Control createDialogArea(Composite parent) {
container = (Composite) super.createDialogArea(parent);
GridDataFactory.fillDefaults().grab(true, true).applyTo(container);
GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(container);
Group group = new Group(container, SWT.NONE);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, false).applyTo(group);
GridLayoutFactory.fillDefaults().applyTo(group);
for (M_ATTRIBUTE attr : M_ATTRIBUTE.values()) {
Button button = new Button(group, SWT.CHECK);
GridDataFactory.fillDefaults().applyTo(button);
button.setText(attr.getDisplayValue());
this.buttons.put(attr, button);
}
stack = new Composite(container, SWT.NONE);
GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(stack);
stackLayout = new StackLayout();
stack.setLayout(stackLayout);
compMultiLine = new Composite(stack, SWT.NONE);
GridDataFactory.fillDefaults().applyTo(compMultiLine);
GridLayoutFactory.fillDefaults().applyTo(compMultiLine);
valueTextMulti = new Text(compMultiLine, SWT.BORDER | SWT.MULTI |SWT.WRAP);
GridDataFactory.fillDefaults().grab(true, true).applyTo(valueTextMulti);
valueTextMulti.addModifyListener(valueTextModifyListener);
compSingleLine = new Composite(stack, SWT.NONE);
GridDataFactory.fillDefaults().applyTo(compSingleLine);
GridLayoutFactory.fillDefaults().applyTo(compSingleLine);
valueTextSingle = new Text(compSingleLine, SWT.BORDER | SWT.SINGLE | SWT.WRAP);
GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(valueTextSingle);
valueTextSingle.addModifyListener(valueTextModifyListener);
stackLayout.topControl = compMultiLine;
return container;
}
@Override
public void selectionChanged(SelectionChangedEvent event) {
IStructuredSelection sel = (IStructuredSelection) event.getSelection();
M_DATA_TYPE type = (M_DATA_TYPE) sel.getFirstElement();
switch (type) {
case LIST:
case HASH_TABLE:
stackLayout.topControl = compMultiLine;
stack.layout();
break;
default:
stackLayout.topControl = compSingleLine;
stack.layout();
break;
}
}