@Override
    protected void fillShape(Graphics graphics) {
      graphics.setAntialias(SWT.ON);
      Pattern pattern = null;
      graphics.setBackgroundColor(GRAY_COLOR);
      boolean support3D = GraphicsUtil.testPatternSupported(graphics);
      if (effect3D && support3D) {
        // add this to eliminate the repaint bug on Mac
        graphics.fillOval(new Rectangle());

        pattern =
            new Pattern(
                Display.getCurrent(),
                bounds.x,
                bounds.y,
                bounds.x + bounds.width,
                bounds.y + bounds.height,
                WHITE_COLOR,
                BORDER_COLOR);
        graphics.setBackgroundPattern(pattern);
      }
      super.fillShape(graphics);
      if (effect3D && support3D) pattern.dispose();
    }
  @Override
  protected void paintClientArea(Graphics graphics) {
    graphics.setAntialias(SWT.ON);
    Rectangle area = getClientArea();
    area.width = Math.min(area.width, area.height);
    area.height = area.width;
    Pattern pattern = null;
    graphics.pushState();
    graphics.setBackgroundColor(GRAY_COLOR);
    boolean support3D = GraphicsUtil.testPatternSupported(graphics);
    if (effect3D && support3D) {
      // add this to eliminate the repaint bug on Mac
      graphics.fillOval(new Rectangle());
      pattern =
          new Pattern(
              Display.getCurrent(),
              area.x,
              area.y,
              area.x + area.width,
              area.y + area.height,
              BORDER_COLOR,
              WHITE_COLOR);
      graphics.setBackgroundPattern(pattern);
    }
    graphics.fillOval(area);
    graphics.popState();

    if (effect3D && support3D) {
      pattern.dispose();
      area.shrink(BORDER_WIDTH, BORDER_WIDTH);
    } else area.shrink(1, 1);

    graphics.fillOval(area);

    super.paintClientArea(graphics);

    // glossy effect
    if (effect3D && support3D) {
      graphics.pushState();
      graphics.setAntialias(SWT.ON);
      final double R = area.width / 2.0d;
      final double UD_FILL_PART = 9.5d / 10d;
      final double UP_DOWN_RATIO = 1d / 2d;
      final double LR_FILL_PART = 8.5d / 10d;
      final double UP_ANGLE = 0d * Math.PI / 180d;
      final double DOWN_ANGLE = 35d * Math.PI / 180d;
      // add this to eliminate the repaint bug on Mac

      graphics.fillOval(new Rectangle());

      Pattern glossyPattern =
          new Pattern(
              Display.getCurrent(),
              area.x + area.width / 2,
              (float) (area.y + area.height / 2 - R * UD_FILL_PART),
              area.x + area.width / 2,
              (float) (area.y + area.height / 2 + R * UP_DOWN_RATIO),
              WHITE_COLOR,
              90,
              WHITE_COLOR,
              0);
      graphics.setBackgroundPattern(glossyPattern);
      Rectangle rectangle =
          new Rectangle(
              (int) (area.x + area.width / 2 - R * LR_FILL_PART * Math.cos(UP_ANGLE)),
              (int) (area.y + area.height / 2 - R * UD_FILL_PART),
              (int) (2 * R * LR_FILL_PART * Math.cos(UP_ANGLE)),
              (int) (R * UD_FILL_PART + R * UP_DOWN_RATIO));
      graphics.fillOval(rectangle);
      glossyPattern.dispose();

      glossyPattern =
          new Pattern(
              Display.getCurrent(),
              area.x + area.width / 2,
              (float) (area.y + area.height / 2 + R * UP_DOWN_RATIO - 1),
              area.x + area.width / 2,
              (float) (area.y + area.height / 2 + R * UD_FILL_PART + 1),
              WHITE_COLOR,
              0,
              WHITE_COLOR,
              40);
      graphics.setBackgroundPattern(glossyPattern);
      rectangle =
          new Rectangle(
              (int) (area.x + area.width / 2 - R * LR_FILL_PART * Math.sin(DOWN_ANGLE)),
              (int) Math.ceil(area.y + area.height / 2 + R * UP_DOWN_RATIO),
              (int) (2 * R * LR_FILL_PART * Math.sin(DOWN_ANGLE)),
              (int) Math.ceil(R * UD_FILL_PART - R * UP_DOWN_RATIO));
      graphics.fillOval(rectangle);
      glossyPattern.dispose();
      graphics.popState();
    }
  }