开发者

DoubleClick Event Handler for GWT Grid

I am using a gwt grid and Im tryi开发者_JAVA技巧ng to get the cell that had the onDoubleClick event on it. So if I was doing onClickEvent I would use getCellForEvent(ClickEvent) and that returns a cell. But that method doesnt accept a DoublClickEvent. How do I get the cell that had the onDoubleClick...?


Extend Grid and use the protected getEventTargetCell to obtain the cell from a NativeEvent instead of a GwtEvent.


I didn't think of that NativeEvent thing. I hope it's portable across browsers. My DataGrid has an extension of ClickableTextCells. The DClickableTextCell ("D" for double-click) reacts to a double-click, which Microsoft defines as two-clicks within 500 milliseconds.

public class DClickableTextCell extends ClickableTextCell {

  @Override
  public void onBrowserEvent(com.google.gwt.cell.client.Cell.Context context, Element parent,
      String value, NativeEvent event, ValueUpdater<String> valueUpdater) {
    String type = event.getType();
    if ((valueUpdater != null) && type.equals("click")) {
      if (DoubleClickTimer.getInstance().isTimerRunning()) {
        event.preventDefault();
        DoubleClickTimer.getInstance().stopTimer();
        valueUpdater.update(value);
      } else {
        DoubleClickTimer.getInstance().startTimer();
      }
    }
  }
}

If the DoubleClick timer is currently running, then this click must the second click of a double-click. If the DoubleClick timer is not currently running, then this is potentially the first click of a DoubleClick. Start the timer. Here's the code for DoubleClickTimer:

public class DoubleClickTimer {

  private static DoubleClickTimer ref = null;

  private DoubleClickTimer() {

  }

  public static DoubleClickTimer getInstance() {
    if (ref == null) {
      ref = new DoubleClickTimer();
    }
    return ref;
  }

  private boolean timerRunning = false;
  private Timer timer = new Timer() {
    @Override
    public void run() {
      timerRunning = false;
    }
  };

  public void startTimer() {
    if (!timerRunning) {
      timer.schedule(500);
      timerRunning = true;
    }
  }

  public boolean isTimerRunning() {
    return timerRunning;
  }

  public void stopTimer() {
    timer.cancel();
    timerRunning = false;
  }

}

It works, but now I'm going to look at extending DataGrid. The problem is that DataGrid refers to protected methods in AbstractCellTable that aren't accessible as soon as you put your DataGrid subclass in a different package. You can bring AbstractCellTable over as well, but then it makes similar references, and you end up copying more stuff.

The call to event.preventDefault suppresses the normal behaviour of a double-click, and that is to highlight the widget being clicked on. Since the whole DataGrid is a single widget (cells and columns are not widgets), every bit of text in the DataGrid gets selected unless you prevent that default behaviour.

I'm not an expert and I'd like to get advice from people on whether I could be doing this better. But it works, so I'm offering it as a possible answer.


You'll need to extend the original cell. In the constructor change:

super("click", "keyup", "keydown", "blur"); to super("dblclick", "keyup", "keydown", "blur");

and in the onBrowserEvent method change:

if ("click".equals(type) || enterPressed) to if ("dblclick".equals(type) || enterPressed)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜