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(ドロップダウンから選択した場合ではない)。これを実現するには、どのリスナーを追加する必要がありますか?コンボビューアにmodifyリスナーを追加すること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 の代わりに Verify イベントを使用することをお勧めします。Verify も Key Event ですが、ALT、CNTRL、SHIFTの組み合わせを除外します。ユーザーがキーコードを入力するときは、keycode!=0 をチェックするだけです。

ご指摘のとおり、 CNTRL+V を使用すると、右クリックメニューの貼り付け....コンボはキーイベントとは見なしませんが、検証イベントを発生させて、クリップボードのテキストがコンボに対して有効かどうかを確認します。メニュー項目の選択とコンボのキーイベントは別のものなので、これがどのように機能するべきだと思います。コピー/貼り付け/削除などの特別なアクションについて、すべての重要なイベントをいつでも監視できます。

上記のサンプル コードは、探しているものを実行できるはずです。

于 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 に答える