my Apps: * COOL MOVIE BROWSER (sports, tv on net) here * MONEY ON THREAD (personal finance) here * HIT-BALL (cute game) here



GWT - How to draw in the browser with GWTCanvas

It's time to have better graphics and drawing capabilities in the Web applications. The big guys are working to support HTML5, but until then, we can use the GWTCanvas widget from the GWT.

Here is a sample of how to extends the base GWTCanvas with more nicer and simpler features, like the mouse and keys events.

/**
 * The class SccCanvas extends GWTCanvas with mouse event listeners.
 *
 * @author SCC
 */
public class SccCanvas extends GWTCanvas {
   /** graphics helper */
   private final SccGraphics graphics_;

   /** Default constructor */
   public SccCanvas() {
      super();
      graphics_ = new SccGraphics(this);
      sinkEvents(Event.MOUSEEVENTS);
   }

   /** Creates a canvas with specified sizes for drawing and pixels */
   public SccCanvas(int coordX, int coordY, int pixelX, int pixelY) {
      super(coordX, coordY, pixelX, pixelY);
      graphics_ = new SccGraphics(this);
      sinkEvents(Event.MOUSEEVENTS);
   }

   /** Creates a canvas with specified size */
   public SccCanvas(int coordX, int coordY) {
      super(coordX, coordY);
      graphics_ = new SccGraphics(this);
      sinkEvents(Event.MOUSEEVENTS);
   }

   public HandlerRegistration addMouseDownHandler(MouseDownHandler handler) {
      return addDomHandler(handler, MouseDownEvent.getType());
   }

   public HandlerRegistration addMouseMoveHandler(MouseMoveHandler handler) {
      return addDomHandler(handler, MouseMoveEvent.getType());
   }

   public HandlerRegistration addMouseOutHandler(MouseOutHandler handler) {
      return addDomHandler(handler, MouseOutEvent.getType());
   }

   public HandlerRegistration addMouseOverHandler(MouseOverHandler handler) {
      return addDomHandler(handler, MouseOverEvent.getType());
   }

   public HandlerRegistration addMouseUpHandler(MouseUpHandler handler) {
      return addDomHandler(handler, MouseUpEvent.getType());
   }

   public HandlerRegistration addMouseWheelHandler(MouseWheelHandler handler) {
      return addDomHandler(handler, MouseWheelEvent.getType());
   }

   /**
    * @return the graphics_;
    */
   public SccGraphics getGraphics() {
      return graphics_;
   }
}


We have defined a helper class, called SccGraphics, similar with the "Graphics" context from Swing to implement the drawing primitives:

/** helper class for the simple drawing primitives */
public class SccGraphics {
   private final SccCanvas canvas_;


   public SccGraphics(final SccCanvas canvas) {
      canvas_ = canvas;
   }


   /** draws a line between 2 points (x1,y1) and (x2,y2) */
   public void drawLine(int x1, int y1, int x2, int y2) {
      canvas_.beginPath();
      canvas_.moveTo(x1, y1);
      canvas_.lineTo(x2, y2);
      canvas_.closePath();
      canvas_.stroke();
   }


   /** draws a rectangle, top corner (x,y) and size (w,h) */
   public void drawRect(int x, int y, int w, int h) {
      canvas_.beginPath();
      canvas_.rect(x, y, w, h);
      canvas_.closePath();
      canvas_.stroke();
   }


   /**
   * Draw an arc.
   * 
   * @param x
   * int value for centre X
   * @param y
   * int value for centre Y
   * @param r
   * int value for radius
   * @param startAngle
   * int value of start angle in degree 0 - 360
   * @param endAngle
   * int value of end angle in degree 0 - 360
   * @param antiClock
   * true value for antiClockwise sense
   */
   public void drawArc(int x, int y, int r, int startAngle, int endAngle,
         boolean antiClock) {
     canvas_.beginPath();
     final double start = Math.PI * startAngle / 180;
     final double end = Math.PI * endAngle / 180;
     canvas_.arc(x, y, r, start, end, antiClock);
     canvas_.closePath();
     canvas_.stroke();
  }
}

And this is the testing code, which allow us to mark the mouse position with a hair-cross lines, and also basic shape of rectangle and circle.

private int startX_;
private int startY_;


public void testGWTCanvas() {
   final SccCanvas c = new SccCanvas(350, 350);
   c.setBackgroundColor(Color.WHITE);


   final SccGraphics g = c.getGraphics();


   RootPanel.get().add(c);
   final Label lbl = new Label();


   c.addMouseMoveHandler(new MouseMoveHandler() {
      @Override
      public void onMouseMove(final MouseMoveEvent event) {
         c.clear();
         int mx = event.getX();
         int my = event.getY();
         lbl.setText(mx + "," + my);


         c.setLineWidth(.20);
         c.setStrokeStyle(Color.BLACK);
         g.drawLine(mx, 0, mx, 350);
         g.drawLine(0, my, 350, my);


         if (startX_ > 0) {


            c.setLineWidth(.65);
            c.setStrokeStyle(Color.RED);
            g.drawRect(startX_, startY_, mx - startX_, my - startY_);
         }
      }
   });


   c.addMouseUpHandler(new MouseUpHandler() {
      @Override
      public void onMouseUp(MouseUpEvent event) {
         int mx = event.getX();
         int my = event.getY();


         c.setLineWidth(1);
         c.setStrokeStyle(Color.GREEN);
         int w = mx - startX_;
         int h = my - startY_;


         g.drawRect(startX_, startY_, w, h);


         int r = Math.min(Math.abs(w / 2), Math.abs(h / 2));
         g.drawArc((startX_ + mx) / 2, (startY_ + my) / 2, r, 0, 360,
         true);


         startX_ = -1;
         startY_ = -1;


      }
   });


   c.addMouseDownHandler(new MouseDownHandler() {
      @Override
      public void onMouseDown(final MouseDownEvent event) {
         int b = event.getNativeButton();
         int mx = event.getX();
         int my = event.getY();
         if (b == NativeEvent.BUTTON_LEFT) {
            lbl.setText("LEFT-CLICK @ " + mx + "," + my);
            startX_ = mx;
            startY_ = my;


         } else if (b == NativeEvent.BUTTON_MIDDLE) {
            lbl.setText("MIDDLE-CLICK @ " + mx + "," + my);


         } else if (b == NativeEvent.BUTTON_RIGHT) {
            lbl.setText("RIGHT-CLICK @ " + mx + "," + my);
         }
      }
   });


   Window win = new Window ();
   win.setBottomComponent(lbl);
   win.setSize (500, 400);
   win.add (c);
   win.show();
}


An here's the result of the above code:



So, it's just matter of time to see very powerful applications and systems. Examples are lots on web http://www.chromeexperiments.com/.

Cheers!

1 comment: