SWT:在组合中区分选择和键入

时间:2012-09-13 16:20:44

标签: java swt jface

考虑以下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(...)向组合查看器添加修改侦听器并不好,因为从组合键入和选择都会触发此操作。

2 个答案:

答案 0 :(得分: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");
  }

我建议你使用Verify事件代替Key UP,因为你可能最终会处理很多事情(箭头键,魔术键......等)。验证也是关键事件,但它过滤掉 ALT,CNTRL,SHIFT 组合。用户类型只检查键码!= 0。

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

上面的示例代码应该能够执行您要查找的内容。

答案 1 :(得分: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();
}