Search code examples
javaswtjface

SWT: Differentiating between selection and typing in a combo


Consider the following Java (SWT) code:

private static ComboViewer createViewer(final Shell shell) {
  final ComboViewer v = new ComboViewer(shell, SWT.DROP_DOWN);
  v.setLabelProvider(new LabelProvider());
  v.setContentProvider(new ArrayContentProvider());
  v.setInput(new String[]{"value 1", "value 2"});
  return v;
}

public static void main(final String[] args) {
  Display display = new Display();
  Shell shell = new Shell(display);
  shell.setSize(200, 60); 
  shell.setLayout(new GridLayout());

  final ComboViewer v = createViewer(shell);

  // This wires up the userSelectedSomething method correctly
  v.addSelectionChangedListener(new ISelectionChangedListener() {
    @Override
    public void selectionChanged(final SelectionChangedEvent event) {
      userSelectedSomething();
    }
  });

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

public static void userSelectedSomething() {
  // This should be called *only if* the user selected from the drop-down
}

public static void userTypedSomething() {
  // This should be called *only if* the user typed in the combo
}

I want to call the userTypedSomething method only if the user typed into the combo (and not when they selected from the drop-down). What listener should I add to achieve this? Adding a modify listener to the combo viewer with v.getCombo().addModifyListener(...) is no good as this is triggered for both typing and selection from the combo.


Solution

  • Since you want to listen to keyboard input, I would suggest listening to SWT.KeyUp.

    This should be a good starting point:

    public static void main(String[] args) {
        final Display display = new Display();
        final Shell shell = new Shell(display);
        shell.setLayout(new FillLayout());
    
        final Combo combo = new Combo(shell, SWT.NONE);
    
        combo.add("First");
        combo.add("Second");
    
        combo.addListener(SWT.Selection, new Listener() {
    
            @Override
            public void handleEvent(Event arg0) {
                System.out.println("Selected: " + combo.getItem(combo.getSelectionIndex()));
            }
        });
    
        combo.addListener(SWT.KeyUp, new Listener() {
    
            @Override
            public void handleEvent(Event arg0) {
                System.out.println("Typed");
            }
        });
    
        shell.pack();
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
        display.dispose();
    }