为Eclipse Text控件实现“select on focus”行为

时间:2012-04-06 02:48:48

标签: java eclipse textbox swt eclipse-3.6

目标

我正在尝试为Eclipse Text控件实现“select on focus”行为:

  • 当控件已经聚焦时:

    • 点击和拖动行为正常
  • 当控件聚焦时:

    • 点击并拖动以选择文字正常行为

    • 点击而不选择文字将选择所有文字

    • 使用键盘进行对焦将选择所有文字

问题

  • 只需选择SWT.FocusIn的所有文字,只需点击鼠标即可选择文字。

  • SWT.FocusInSWT.MouseDown之前被解雇 ,因此当用户按下时无法判断控件是否已经有焦点鼠标向下。

问题

  1. 为什么Eclipse会按顺序触发事件?这对我没有任何意义。这是对某些支持的操作系统的限制吗?

  2. 我可以使用一些解决方法来实现此功能吗?

1 个答案:

答案 0 :(得分:3)

#eclipse中的某个人将我与很久以前提出的Eclipse错误联系起来:Can't use focus listener to select all text

使用其中一个建议,我想出了以下解决方案(在Windows中运行,在其他平台上未经测试):

/**
 * This method adds select-on-focus functionality to a {@link Text} component.
 * 
 * Specific behavior:
 *  - when the Text is already focused -> normal behavior
 *  - when the Text is not focused:
 *    -> focus by keyboard -> select all text
 *    -> focus by mouse click -> select all text unless user manually selects text
 * 
 * @param text
 */
public static void addSelectOnFocusToText(Text text) {
  Listener listener = new Listener() {

    private boolean hasFocus = false;
    private boolean hadFocusOnMousedown = false;

    @Override
    public void handleEvent(Event e) {
      switch(e.type) {
        case SWT.FocusIn: {
          Text t = (Text) e.widget;

          // Covers the case where the user focuses by keyboard.
          t.selectAll();

          // The case where the user focuses by mouse click is special because Eclipse,
          // for some reason, fires SWT.FocusIn before SWT.MouseDown, and on mouse down
          // it cancels the selection. So we set a variable to keep track of whether the
          // control is focused (can't rely on isFocusControl() because sometimes it's wrong),
          // and we make it asynchronous so it will get set AFTER SWT.MouseDown is fired.
          t.getDisplay().asyncExec(new Runnable() {
            @Override
            public void run() {
              hasFocus = true;
            }
          });

          break;
        }
        case SWT.FocusOut: {
          hasFocus = false;
          ((Text) e.widget).clearSelection();

          break;
        }
        case SWT.MouseDown: {
          // Set the variable which is used in SWT.MouseUp.
          hadFocusOnMousedown = hasFocus;

          break;
        }
        case SWT.MouseUp: {
          Text t = (Text) e.widget;
          if(t.getSelectionCount() == 0 && !hadFocusOnMousedown) {
            ((Text) e.widget).selectAll();
          }

          break;
        }
      }
    }

  };

  text.addListener(SWT.FocusIn, listener);
  text.addListener(SWT.FocusOut, listener);
  text.addListener(SWT.MouseDown, listener);
  text.addListener(SWT.MouseUp, listener);
}