Paintbrush

Here is an example showing a more dynamic use of JWt's vector graphics API.

JWt's WPaintedWidget renders as SVG, VML or HTML5 graphics depending on the capabilities of the browser. The backend decides how to render the graphics, the application programmer has to draw his graphics using the available methods in the WPainter API. The drawing primitives include points, lines, arcs, cubic splines, text, etc.

The update() method of WPaintedWidget is called with the PaintUpdate rendering flag to update the canvas without clearing the previously painted contents (which is the default behavior).

Every mouse drag operation on the simple painting device is sent to the server, which in turn updates the canvas. You could imagine more interesting use cases, such as a multi-user white board, or interactive visualizations.

You can use a custom cursor image (pencil) by providing a cursor image to WCssDecorationStyle.

Example
source
  class PaintBrush extends WPaintedWidget {
    private static Logger logger = LoggerFactory.getLogger(PaintBrush.class);

    PaintBrush(int width, int height, WContainerWidget parentContainer) {
      super();
      this.path_ = new WPainterPath();
      this.color_ = new WColor();
      this.resize(new WLength(width), new WLength(height));
      this.getDecorationStyle().setCursor("icons/pencil.cur", Cursor.Cross);
      this.mouseDragged()
          .addListener(
              this,
              (WMouseEvent e1) -> {
                PaintBrush.this.mouseDrag(e1);
              });
      this.mouseWentDown()
          .addListener(
              this,
              (WMouseEvent e1) -> {
                PaintBrush.this.mouseDown(e1);
              });
      this.touchStarted()
          .addListener(
              this,
              (WTouchEvent e1) -> {
                PaintBrush.this.touchStart(e1);
              });
      this.touchMoved()
          .addListener(
              this,
              (WTouchEvent e1) -> {
                PaintBrush.this.touchMove(e1);
              });
      this.touchMoved().preventDefaultAction();
      this.color_ = new WColor(StandardColor.Black);
      if (parentContainer != null) parentContainer.addWidget(this);
    }

    public PaintBrush(int width, int height) {
      this(width, height, (WContainerWidget) null);
    }

    void clear() {
      this.update();
    }

    void setColor(final WColor c) {
      this.color_ = c;
    }

    void paintEvent(WPaintDevice paintDevice) {
      WPainter painter = new WPainter(paintDevice);
      painter.setRenderHint(RenderHint.Antialiasing);
      WPen pen = new WPen();
      pen.setWidth(new WLength(3));
      pen.setColor(this.color_);
      pen.setCapStyle(PenCapStyle.Flat);
      pen.setJoinStyle(PenJoinStyle.Miter);
      painter.setPen(pen);
      painter.drawPath(this.path_);
      this.path_.assign(new WPainterPath(this.path_.getCurrentPosition()));
    }

    private WPainterPath path_;
    private WColor color_;

    void mouseDown(final WMouseEvent e) {
      Coordinates c = e.getWidget();
      this.path_.assign(new WPainterPath(new WPointF(c.x, c.y)));
    }

    void mouseDrag(final WMouseEvent e) {
      Coordinates c = e.getWidget();
      this.path_.lineTo(c.x, c.y);
      this.update(EnumSet.of(PaintFlag.Update));
    }

    void touchStart(final WTouchEvent e) {
      Coordinates c = e.getTouches().get(0).getWidget();
      this.path_.assign(new WPainterPath(new WPointF(c.x, c.y)));
    }

    void touchMove(final WTouchEvent e) {
      Coordinates c = e.getTouches().get(0).getWidget();
      this.path_.lineTo(c.x, c.y);
      this.update(EnumSet.of(PaintFlag.Update));
    }
  }

  WPushButton createColorToggle(String className, final WColor color, final PaintBrush canvas) {
    WPushButton button = new WPushButton();
    button.setTextFormat(TextFormat.XHTML);
    button.setText(" ");
    button.setCheckable(true);
    button.addStyleClass(className);
    button.setWidth(new WLength(30));
    button
        .checked()
        .addListener(
            this,
            () -> {
              canvas.setColor(color);
            });
    return button;
  }

  void Paintbrush() {
    final WColor blue = new WColor("#0d6efd");
    final WColor red = new WColor("#dc3545");
    final WColor green = new WColor("#198754");
    final WColor yellow = new WColor("#ffc107");
    final WColor black = new WColor(StandardColor.Black);
    final WColor gray = new WColor("#6c757d");
    WContainerWidget result = new WContainerWidget();
    PaintBrush canvas = new PaintBrush(710, 400);
    final PaintBrush canvas_ = canvas;
    canvas.setColor(blue);
    canvas
        .getDecorationStyle()
        .setBorder(new WBorder(BorderStyle.Solid, BorderWidth.Medium, black));
    List<WPushButton> colorButtons = new ArrayList<WPushButton>();
    colorButtons.add(createColorToggle("btn-blue", blue, canvas));
    colorButtons.add(createColorToggle("btn-danger", red, canvas));
    colorButtons.add(createColorToggle("btn-success", green, canvas));
    colorButtons.add(createColorToggle("btn-warning", yellow, canvas));
    colorButtons.add(createColorToggle("btn-black", black, canvas));
    colorButtons.add(createColorToggle("btn-secondary", gray, canvas));
    WToolBar toolBar = new WToolBar();
    for (int i = 0; i < colorButtons.size(); ++i) {
      WPushButton button = colorButtons.get(i);
      button.setChecked(i == 0);
      toolBar.addButton(button);
      for (int j = 0; j < colorButtons.size(); ++j) {
        if (i != j) {
          final WPushButton other = colorButtons.get(j);
          button
              .checked()
              .addListener(
                  other,
                  () -> {
                    other.setUnChecked();
                  });
        }
      }
    }
    WPushButton clearButton = new WPushButton("Clear");
    clearButton
        .clicked()
        .addListener(
            this,
            () -> {
              canvas_.clear();
            });
    toolBar.addSeparator();
    toolBar.addButton(clearButton);
    result.addWidget(toolBar);
    result.addWidget(canvas);
  }

Top