fredsa / gwt-dnd

Library providing easy to use mouse or touch based drag-and-drop capabilities to GWT
43 stars 41 forks source link

Improve type safety of Widgets / SourcesMouseEvents parameters in MouseDragHandler #68

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Type safety on MouseDragHandler can be improved:

  Instead of runtime checking:

    void makeDraggable(Widget draggable, Widget dragHandle) {
        if (dragHandle instanceof SourcesMouseEvents) {
            ((SourcesMouseEvents) dragHandle).addMouseListener(this);
            dragHandleMap.put(dragHandle, draggable);
        }
        else {
            throw new RuntimeException(
                "dragHandle must implement SourcesMouseEvents to be
draggable");
        }
    }

  You can enforce the types at compile time:

    <T extends Widget & SourcesMouseEvents> void makeDraggable(T draggable,
Widget dragHandle) {
        ((SourcesMouseEvents) dragHandle).addMouseListener(this);
        dragHandleMap.put(dragHandle, draggable);
    }

Original issue reported on code.google.com by mark.ren...@gmail.com on 1 May 2009 at 7:22

GoogleCodeExporter commented 9 years ago
Thanks for the suggestion, Mark.

Unfortunately updating the MouseDragHandler method to look like this...
  <T extends HasMouseDownHandlers & HasMouseOutHandlers> void makeDraggable(Widget draggable, T 
dragHandle) {...}

...ends up causing problems in the (Abstract)DragController#makeDraggable 
methods.

If you can think of a way to fix the remaining method signatures as well, I'd 
love to hear it. (The latest source 
in 'trunk' uses Mouse Handlers introduced in GWT 1.6 instead of the familiar 
Mouse Listeners of GWT 1.5.)

Original comment by fredsa on 2 May 2009 at 3:25

GoogleCodeExporter commented 9 years ago
Ok, I see what you mean. I was going to suggest this:

    public interface HasDragHandle {
      <T extends Widget & HasMouseDownHandlers & HasMouseMoveHandlers &
HasMouseUpHandlers> T getDragHandle();
    }

    class AbstractDragControler {  
      <T extends Widget & HasMouseDownHandlers & HasMouseMoveHandlers &
HasMouseUpHandlers> void makeDraggable(T draggable) {
        ...
      }

      <T extends Widget & HasDragHandle> void makeDraggable(T draggable) {
        ...       
      }
    }

But due to type erasure both those methods end up as "makeDraggable(Widget)" 
which
isn't allowed. 

Interestingly, if you don't inlcude Widget in the list of supertypes, it's 
legal:

    public interface HasDragHandle {
      <T extends Widget & HasMouseDownHandlers & HasMouseMoveHandlers &
HasMouseUpHandlers> T getDragHandle();
    }

    class AbstractDragControler {  
      <T extends HasMouseDownHandlers & HasMouseMoveHandlers & HasMouseUpHandlers>
void foo(T val) {
        ...
      }

      <T extends HasDragHandle> void foo(T val) {
        ...        
      }
    }

Though, you probably still need the Widget reference to use with the code, so 
I'm not
sure this is helpful either.

Original comment by mark.ren...@gmail.com on 2 May 2009 at 9:28

GoogleCodeExporter commented 9 years ago
Thanks again. I tried the same (after your suggestion), but indeed needed to 
access at least one Widget method 
:(

I'm setting status to WontFix for now. Let me know if you think of a way to do 
this and we'll reopen.

Original comment by fredsa on 3 May 2009 at 6:07