2

考虑以下 Java (SWT) 代码:

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
}

我只想userTypedSomething在用户输入组合时调用该方法(而不是当他们从下拉列表中选择时)。我应该添加什么监听器来实现这一点?将修改侦听器添加到组合查看器v.getCombo().addModifyListener(...)并不好,因为这会触发组合中的键入和选择。

4

2 回答 2

4
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;
  }

  private static boolean userTyped;
  private static int index = -1;

  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);
    /*
     * invoked multiple times when combo selection happens
     * invoked once when user types
     */
    v.getCombo().addVerifyListener(new VerifyListener() {



      @Override
      public void verifyText(VerifyEvent e) {
         userTyped = (e.keyCode != 0);
      }
    });



 v.getCombo().addModifyListener(new ModifyListener() {

  @Override
  public void modifyText(ModifyEvent e) {

    Combo c = (Combo)e.widget;

    if(userTyped || index == c.getSelectionIndex() || c.getSelectionIndex() == -1)
    {
      userTypedOrEditedSomething();
    }
    index = c.getSelectionIndex();
  }
});

    // 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
    System.out.println("User selected");
  }

  public static void userTypedOrEditedSomething() {
    // This should be called *only if* the user typed in the combo
    System.out.println("User typed or edited");
  }

我建议您使用验证事件而不是 Key UP,因为您最终可能会处理很多事情(箭头键、魔术键等)。验证也是关键事件,但它会过滤掉ALT、CNTRL、SHIFT组合。当用户键入时,只需检查 keycode!=0。

正如您所指出的,当您使用 CNTRL+V 时,右键单击 Menu paste....combo 不会将其视为关键事件,但它会触发验证事件以确保剪贴板文本对组合有效。我认为这就是它应该如何工作,因为菜单项选择和组合键事件是不同的事情。您可以随时监控所有关键事件以进行复制/粘贴/删除等特殊操作。

上面的示例代码应该能够执行您正在寻找的内容。

于 2012-09-14T16:46:39.383 回答
2

由于您想听键盘输入,我建议您听SWT.KeyUp.

这应该是一个很好的起点:

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();
}
于 2012-09-13T16:23:59.523 回答