SWT - 如何动态更改文本框的大小

SWT - How to change the size of Text box dynamically

我正在尝试创建一个简单的 UI,其中包含一个组合、一个文本框和一个浏览按钮。该组合将包含两个值:Execution TimesExecute with File。 选择 Execution Times 选项时,应显示后跟文本框的组合框。

选择使用文件执行选项时,应显示组合框、文本框和浏览按钮。

当我在这些选项之间切换时,小部件没有正确对齐。请参考下图。文本框大小未扩展到可用 space。

public class TestUI {

    public static void main(String[] args)
    {
        Display display = new Display();
        final Shell shell = new Shell(display);
        shell.setText("Whosebug");
        shell.setLayout(new GridLayout(1, true));

        Composite composite = new Composite(shell, SWT.NONE);
        composite.setLayout(new GridLayout(3, false));
        composite.setLayoutData(new GridData(GridData.FILL_BOTH));

        Combo combo = new Combo(composite, SWT.READ_ONLY);
        String[] input = { "Execution Times", "Execute with File" };
        combo.setItems(input);

        Text loopText = new Text(composite, SWT.SINGLE | SWT.BORDER);
        GridData gridData = new GridData(SWT.BEGINNING | GridData.FILL_HORIZONTAL);
        gridData.horizontalSpan = 2;
        loopText.setLayoutData(gridData);
        loopText.setEnabled(false);

        Button browseButton = new Button(composite, SWT.PUSH);
        browseButton.setText("Browse...");
        browseButton.setVisible(false);

        combo.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                String text2 = combo.getText();
                System.out.println(text2);

                if (text2.equals("Execution Times")) {
                    loopText.setEnabled(true);
                    loopText.setText("1");//$NON-NLS-1$
                    GridData gridData1 = new GridData(SWT.BEGINNING, SWT.TOP, false, false);
                    gridData1.grabExcessHorizontalSpace = true;
                    gridData1.horizontalSpan = 2;
                    loopText.setLayoutData(gridData1);
                    browseButton.setVisible(false);
                    loopText.getParent().layout();
                }
                if (text2.equals("Execute with File")) {
                    GridData gridData1 = new GridData(SWT.BEGINNING, SWT.TOP, false, false);
                    gridData1.grabExcessHorizontalSpace = true;
                    loopText.setLayoutData(gridData1);
                    gridData.exclude= false;
                    browseButton.setVisible(true);
                    browseButton.setFocus();
                    loopText.setText("");
                    loopText.setEnabled(false);
                    loopText.getParent().layout();
                }
            }

        });

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

谁能帮我解决这个问题?

对于初学者来说,您不需要每次都为 Text 小部件重新创建 GridData。相反,只需通过 gridData.horizontalSpan 修改原始文件,或者如果在实践中您无权访问 GridData 实例,您可以通过 ((GridData) gridData.getLayoutData()).horizontalSpan 等获得它。

您在 Shell 底部看到空白 space 的原因是您创建了一个包含 3 列的布局,然后添加了以下内容:

  1. Combo
  2. TexthorizontalSpan 设置为 2,因此使用 2 列)
  3. Button

ComboText 占据了所有 3 列,因此为 Button 添加了一个新行。然后你调用 pack(),计算出首选大小,这将是 2 行,第一行的大小仅为 2 个小部件。

我们可以通过 Shell.setSize(...)Shell 上设置一个大小,而不是调用 pack() 并将 Shell 的大小缩小到首选大小。一般来说,您不想混合使用 setSize(...) 和布局,但是您已经用 "RCP" 标记了 post,因此您的 Shell 已经有了尺寸,您赢了'手动调用 pack()open().

完整示例:

public static void main(String[] args) {
    Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setSize(300, 80);
    shell.setText("Whosebug");
    shell.setLayout(new GridLayout(1, true));

    Composite composite = new Composite(shell, SWT.NONE);
    composite.setLayout(new GridLayout(3, false));
    composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

    final Combo combo = new Combo(composite, SWT.READ_ONLY);
    String[] input = {"Execution Times", "Execute with File"};
    combo.setItems(input);

    final Text loopText = new Text(composite, SWT.SINGLE | SWT.BORDER);
    final GridData textGridData = new GridData(SWT.FILL, SWT.FILL, true, false);
    textGridData.horizontalSpan = 2;
    loopText.setLayoutData(textGridData);
    loopText.setEnabled(false);

    final Button browseButton = new Button(composite, SWT.PUSH);
    browseButton.setText("Browse...");
    browseButton.setVisible(false);

    combo.addSelectionListener(new SelectionAdapter() {

        @Override
        public void widgetSelected(SelectionEvent e) {
            String text2 = combo.getText();
            System.out.println(text2);

            if (text2.equals("Execution Times")) {
                loopText.setEnabled(true);
                loopText.setText("1");

                // Can also do ((GridData) textGridData.getLayoutData())...
                textGridData.grabExcessHorizontalSpace = true;
                textGridData.horizontalSpan = 2;

                browseButton.setVisible(false);
                loopText.getParent().layout();
            }
            if (text2.equals("Execute with File")) {
                loopText.setEnabled(false);
                loopText.setText("");

                textGridData.grabExcessHorizontalSpace = true;
                textGridData.horizontalSpan = 1;

                browseButton.setVisible(true);
                browseButton.setFocus();
                loopText.getParent().layout();
            }
        }

    });

    shell.open();

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

或者,如果您实际上是在创建和打开一个新的 Shell,则在使 Text 小部件占据两列之前调用 pack()(以获得首选大小) :

shell.pack();

// Move these two lines down to the end
textGridData.horizontalSpan = 2;
browseButton.setVisible(false);
shell.layout(true, true);

shell.open();

我们所做的是在不调整 horizontalSpan 的情况下添加所有 3 个小部件。然后,假设所有 3 个小部件都出现在一行中,调用 pack() 设置 Shell 的大小。调用pack()后,设置horizontalSpan为2,隐藏Button。当 Shell 打开时,您将看到:

据我了解,根据组合选择,文本字段和文本字段加按钮有不同的用途:

  • when Execution Times is selected, the number of times is to be entered
  • 否则 使用文件执行 需要输入或浏览文件名

因此,我会在组合小部件旁边使用 Composite 来容纳用于输入数字(甚至 Spinner)的文本字段或用于 [=] 的文本字段和按钮32=]一个文件名。

Composite composite = new Composite( parent, SWT.NONE );
Text executionTimesText = new Text( composite, SWT.BORDER );
composite.setLayout( new StackLayout() );
Composite executionFileComposite = new Composite( composite, SWT.NONE );
// use a GridLayout to position the file name text field and button within the executionFileComposite
combo.addListener( SWT.Selection, event -> {
  StackLayout layout = ( StackLayout )composite.getLayout();
  if( combo.getSelectionIndex() == 0 ) {
    layout.topControl = executionTimesText;
  } else if( combo.getSelectionIndex() == 1 ) {
    layout.topControl = executionFileComposite;
  }
  composite.layout();
}

StackLayout 允许您堆叠 不同的输入字段并根据需要在它们之间切换(即根据组合的选择)。