Search code examples
swteclipse-rcprcp

SWT - How to change the size of Text box dynamically


I am trying to create a Simple UI which contains a combo, a text box and a browse button. The combo will be containing two values: Execution Times and Execute with File. When the Execution Times option is selected, the combo box followed by a text box should be displayed. enter image description here

enter image description here

when the Execute with File option is selected, the combo box, a text box, and a browse button should be displayed.

enter image description here

When I am switching between these options, the widgets are not getting aligned properly. Refer to the below image. The text box size is not getting expanded to the available space. Image 4

public class TestUI {

    public static void main(String[] args)
    {
        Display display = new Display();
        final Shell shell = new Shell(display);
        shell.setText("StackOverflow");
        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();
    }
}

Can any one help me on this?


Solution

  • From what I understand, depending on the combo selection, the text field and text field plus button serve different purposes:

    • when Execution Times is selected, the number of times is to be entered
    • otherwise Execute with File requires a file name to be entered or browsed for

    Therefore, I would use a Composite next to the combo widget to hold either a text field to enter a number (or even a Spinner) or a text field and button to enter/select a file name.

    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();
    }
    

    The StackLayout allows you to stack the different input fields and switch betwen them as needed (i.e. according to the combo's selection).