public void paint(Graphics gg) {
    int faceSize = Math.min(getWidth() - 4, getHeight() - 4);
    if (face == null)
      face =
          new PADFaceMapped(
              Math.max(2, (getWidth() - faceSize) / 2),
              Math.max(2, (getHeight() - faceSize) / 2),
              faceSize);
    if (buffer == null) {
      im = this.createImage(getWidth(), getHeight());
      buffer = im.getGraphics();
    }
    super.paint(buffer);

    buffer.setColor(new Color(255, 255, 255, 0));
    buffer.fillRect(0, 0, im.getWidth(null), im.getHeight(null));

    face.setDimensions(
        Math.max(2, (getWidth() - faceSize) / 2),
        Math.max(2, (getHeight() - faceSize) / 2),
        faceSize);
    face.paint(buffer);

    // draw buffer to screen
    gg.drawImage(im, 0, 0, null, null);
  }
  public void setXY(double x, double y) {
    // not validated
    // x and y between -1 and 1
    double sigmoidSteepness, sigmoidZero, baseLength;
    double sensitivity =
        1.1; // evaluated with set to 1.1: a sensitivity of 1 means the complete space of the button
             // is used. 2 means only the middle part is used, making it more sensitive and more
             // easy to get to extreme arousal (from a CHI perspective).
    if (!down) {
      p = x * sensitivity;
      d = y * sensitivity;
      baseLength = Math.max(Math.abs(p), Math.abs(d)); // MAX (P, D) base
      // baseLength=Math.sqrt(Math.pow(p,2)+Math.pow(d,2))/Math.sqrt(2.0); //euclid P,D base

      // now do the mapping to arousal.
      // Arousal is controlled simple by using a Sigmoid function based on length of PD vector
      sigmoidSteepness = 11;
      sigmoidZero = 8;
      a = 2 / (1 + Math.exp(-(sigmoidSteepness * baseLength - sigmoidZero))) - 1;
      a_base = a;
      // Arousal is controlled simply by using a quadratic function that has 0,0,0 as middle point,
      // then drops to -1, then to 1 based MIN (P,D) length (mimics better original linear)
      // sigmoidSteepness=6;
      // sigmoidZero=0.35;
      // a=sigmoidSteepness*Math.pow(Math.max(Math.abs(p),Math.abs(d))-sigmoidZero, 2)-1;

      p = (p > 1 ? 1 : (p < -1 ? -1 : p));
      d = (d > 1 ? 1 : (d < -1 ? -1 : d));
      a = (a > 1 ? 1 : (a < -1 ? -1 : a));

    } else {
      double tmp_p, tmp_d;
      tmp_p = x * sensitivity;
      tmp_d = y * sensitivity;
      baseLength = Math.max(Math.abs(tmp_p), Math.abs(tmp_d)); // MAX (P, D) base
      // baseLength=Math.sqrt(Math.pow(p,2)+Math.pow(d,2))/Math.sqrt(2.0); //euclid P,D base

      // now do the mapping to arousal.
      // Arousal is controlled simple by using a Sigmoid function based on length of PD vector
      sigmoidSteepness = 11;
      sigmoidZero = 8;
      // a=a_base-(d-tmp_d)+2/(1+Math.exp(-(sigmoidSteepness*baseLength-sigmoidZero)))-1;
      a = tmp_d;
      // Arousal is controlled simply by using a quadratic function that has 0,0,0 as middle point,
      // then drops to -1, then to 1 based MIN (P,D) length (mimics better original linear)
      // sigmoidSteepness=6;
      // sigmoidZero=0.35;
      // a=sigmoidSteepness*Math.pow(Math.max(Math.abs(p),Math.abs(d))-sigmoidZero, 2)-1;

      // p=(p>1?1:(p<-1?-1:p));
      // d=(d>1?1:(d<-1?-1:d));
      a = (a > 1 ? 1 : (a < -1 ? -1 : a));
    }
  }