gwtUser
gwtUser

Reputation: 21

DoubleClick Event Handler for GWT Grid

I am using a gwt grid and Im trying 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...?

Upvotes: 2

Views: 2505

Answers (3)

YoungDinosaur
YoungDinosaur

Reputation: 1560

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)

Upvotes: 0

Steve J
Steve J

Reputation: 2674

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.

Upvotes: 1

Ionuț G. Stan
Ionuț G. Stan

Reputation: 179189

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

Upvotes: 1

Related Questions