public Shape createShape(final Alignment alignment,final float stroke){
  float w=getSize().width - 2 * CORNER_RADIUS - stroke;
  float h=getSize().height - 2 * CORNER_RADIUS - stroke;
  float o=CORNER_RADIUS;
  GeneralPath gp=new GeneralPath();
switch (alignment) {
case TOPLEFT:
    gp.moveTo(0,0);
  gp.lineTo(0,h + o);
gp.quadTo(0,h + 2 * o,o,h + 2 * o);
gp.lineTo(w + o,h + 2 * o);
gp.quadTo(w + 2 * o,h + 2 * o,w + 2 * o,h + o);
gp.lineTo(w + 2 * o,2 * o);
gp.quadTo(w + 2 * o,o,w + o,o);
gp.lineTo(o,o);
gp.closePath();
break;
case TOPRIGHT:
gp.moveTo(0,2 * o);
gp.lineTo(0,h + o);
gp.quadTo(0,h + 2 * o,o,h + 2 * o);
gp.lineTo(w + o,h + 2 * o);
gp.quadTo(w + 2 * o,h + 2 * o,w + 2 * o,h + o);
gp.lineTo(w + 2 * o,0);
gp.lineTo(w + o,o);
gp.lineTo(o,o);
gp.quadTo(0,o,0,2 * o);
break;
case BOTTOMLEFT:
gp.moveTo(0,o);
gp.lineTo(0,h + 2 * o);
gp.lineTo(o,h + o);
gp.lineTo(w + o,h + o);
gp.quadTo(w + 2 * o,h + o,w + 2 * o,h);
gp.lineTo(w + 2 * o,o);
gp.quadTo(w + 2 * o,0,w + o,0);
gp.lineTo(o,0);
gp.quadTo(0,0,0,o);
break;
case BOTTOMRIGHT:
gp.moveTo(0,o);
gp.lineTo(0,h);
gp.quadTo(0,h + o,o,h + o);
gp.lineTo(w + o,h + o);
gp.lineTo(w + 2 * o,h + 2 * o);
gp.lineTo(w + 2 * o,o);
gp.quadTo(w + 2 * o,0,w + o,0);
gp.lineTo(o,0);
gp.quadTo(0,0,0,o);
break;
case LEFTBOTTOM:
gp.moveTo(0,h + 2 * o);
gp.lineTo(w + o,h + 2 * o);
gp.quadTo(w + 2 * o,h + 2 * o,w + 2 * o,h + o);
gp.lineTo(w + 2 * o,o);
gp.quadTo(w + 2 * o,0,w + o,0);
gp.lineTo(2 * o,0);
gp.quadTo(o,0,o,o);
gp.lineTo(o,h + o);
gp.closePath();
break;
case INNERLEFT:
case LEFTTOP:
gp.moveTo(0,0);
gp.lineTo(o,o);
gp.lineTo(o,h + o);
gp.quadTo(o,h + 2 * o,2 * o,h + 2 * o);
gp.lineTo(w + o,h + 2 * o);
gp.quadTo(w + 2 * o,h + 2 * o,w + 2 * o,h + o);
gp.lineTo(w + 2 * o,o);
gp.quadTo(w + 2 * o,0,w + o,0);
gp.lineTo(0,0);
break;
case RIGHTBOTTOM:
gp.moveTo(0,h + o);
gp.quadTo(0,h + 2 * o,o,h + 2 * o);
gp.lineTo(w + 2 * o,h + 2 * o);
gp.lineTo(w + o,h + o);
gp.lineTo(w + o,o);
gp.quadTo(w + o,0,w,0);
gp.lineTo(o,0);
gp.quadTo(0,0,0,o);
gp.lineTo(0,h + o);
break;
case INNERRIGHT:
case RIGHTTOP:
gp.moveTo(o,0);
gp.quadTo(0,0,0,o);
gp.lineTo(0,h + o);
gp.quadTo(0,h + 2 * o,o,h + 2 * o);
gp.lineTo(w,h + 2 * o);
gp.quadTo(w + o,h + 2 * o,w + o,h + o);
gp.lineTo(w + o,o);
gp.lineTo(w + 2 * o,0);
gp.lineTo(o,0);
break;
case MIDDLE:
gp.moveTo(o,0);
gp.quadTo(0,0,0,o);
gp.lineTo(0,h + o);
gp.quadTo(0,h + 2 * o,o,h + 2 * o);
gp.lineTo(w + o,h + 2 * o);
gp.quadTo(w + 2 * o,h + 2 * o,w + 2 * o,h + o);
gp.lineTo(w + 2 * o,o);
gp.quadTo(w + 2 * o,0,w + o,0);
gp.lineTo(o,0);
break;
default :
}
AffineTransform tx=new AffineTransform();
return gp.createTransformedShape(tx);
}

public Shape createShape ( final Alignment alignment , final float stroke ) { float w = getSize ( ) . width - 2 * CORNER_RADIUS - stroke ; float h = getSize ( ) . height - 2 * CORNER_RADIUS - stroke ; float o = CORNER_RADIUS ; GeneralPath gp = new GeneralPath ( ) ; switch ( alignment ) { case TOPLEFT : gp . moveTo ( 0 , 0 ) ; gp . lineTo ( 0 , h + o ) ; gp . quadTo ( 0 , h + 2 * o , o , h + 2 * o ) ; gp . lineTo ( w + o , h + 2 * o ) ; gp . quadTo ( w + 2 * o , h + 2 * o , w + 2 * o , h + o ) ; gp . lineTo ( w + 2 * o , 2 * o ) ; gp . quadTo ( w + 2 * o , o , w + o , o ) ; gp . lineTo ( o , o ) ; gp . closePath ( ) ; break ; case TOPRIGHT : gp . moveTo ( 0 , 2 * o ) ; gp . lineTo ( 0 , h + o ) ; gp . quadTo ( 0 , h + 2 * o , o , h + 2 * o ) ; gp . lineTo ( w + o , h + 2 * o ) ; gp . quadTo ( w + 2 * o , h + 2 * o , w + 2 * o , h + o ) ; gp . lineTo ( w + 2 * o , 0 ) ; gp . lineTo ( w + o , o ) ; gp . lineTo ( o , o ) ; gp . quadTo ( 0 , o , 0 , 2 * o ) ; break ; case BOTTOMLEFT : gp . moveTo ( 0 , o ) ; gp . lineTo ( 0 , h + 2 * o ) ; gp . lineTo ( o , h + o ) ; gp . lineTo ( w + o , h + o ) ; gp . quadTo ( w + 2 * o , h + o , w + 2 * o , h ) ; gp . lineTo ( w + 2 * o , o ) ; gp . quadTo ( w + 2 * o , 0 , w + o , 0 ) ; gp . lineTo ( o , 0 ) ; gp . quadTo ( 0 , 0 , 0 , o ) ; break ; case BOTTOMRIGHT : gp . moveTo ( 0 , o ) ; gp . lineTo ( 0 , h ) ; gp . quadTo ( 0 , h + o , o , h + o ) ; gp . lineTo ( w + o , h + o ) ; gp . lineTo ( w + 2 * o , h + 2 * o ) ; gp . lineTo ( w + 2 * o , o ) ; gp . quadTo ( w + 2 * o , 0 , w + o , 0 ) ; gp . lineTo ( o , 0 ) ; gp . quadTo ( 0 , 0 , 0 , o ) ; break ; case LEFTBOTTOM : gp . moveTo ( 0 , h + 2 * o ) ; gp . lineTo ( w + o , h + 2 * o ) ; gp . quadTo ( w + 2 * o , h + 2 * o , w + 2 * o , h + o ) ; gp . lineTo ( w + 2 * o , o ) ; gp . quadTo ( w + 2 * o , 0 , w + o , 0 ) ; gp . lineTo ( 2 * o , 0 ) ; gp . quadTo ( o , 0 , o , o ) ; gp . lineTo ( o , h + o ) ; gp . closePath ( ) ; break ; case INNERLEFT : case LEFTTOP : gp . moveTo ( 0 , 0 ) ; gp . lineTo ( o , o ) ; gp . lineTo ( o , h + o ) ; gp . quadTo ( o , h + 2 * o , 2 * o , h + 2 * o ) ; gp . lineTo ( w + o , h + 2 * o ) ; gp . quadTo ( w + 2 * o , h + 2 * o , w + 2 * o , h + o ) ; gp . lineTo ( w + 2 * o , o ) ; gp . quadTo ( w + 2 * o , 0 , w + o , 0 ) ; gp . lineTo ( 0 , 0 ) ; break ; case RIGHTBOTTOM : gp . moveTo ( 0 , h + o ) ; gp . quadTo ( 0 , h + 2 * o , o , h + 2 * o ) ; gp . lineTo ( w + 2 * o , h + 2 * o ) ; gp . lineTo ( w + o , h + o ) ; gp . lineTo ( w + o , o ) ; gp . quadTo ( w + o , 0 , w , 0 ) ; gp . lineTo ( o , 0 ) ; gp . quadTo ( 0 , 0 , 0 , o ) ; gp . lineTo ( 0 , h + o ) ; break ; case INNERRIGHT : case RIGHTTOP : gp . moveTo ( o , 0 ) ; gp . quadTo ( 0 , 0 , 0 , o ) ; gp . lineTo ( 0 , h + o ) ; gp . quadTo ( 0 , h + 2 * o , o , h + 2 * o ) ; gp . lineTo ( w , h + 2 * o ) ; gp . quadTo ( w + o , h + 2 * o , w + o , h + o ) ; gp . lineTo ( w + o , o ) ; gp . lineTo ( w + 2 * o , 0 ) ; gp . lineTo ( o , 0 ) ; break ; case MIDDLE : gp . moveTo ( o , 0 ) ; gp . quadTo ( 0 , 0 , 0 , o ) ; gp . lineTo ( 0 , h + o ) ; gp . quadTo ( 0 , h + 2 * o , o , h + 2 * o ) ; gp . lineTo ( w + o , h + 2 * o ) ; gp . quadTo ( w + 2 * o , h + 2 * o , w + 2 * o , h + o ) ; gp . lineTo ( w + 2 * o , o ) ; gp . quadTo ( w + 2 * o , 0 , w + o , 0 ) ; gp . lineTo ( o , 0 ) ; break ; default : } AffineTransform tx = new AffineTransform ( ) ; return gp . createTransformedShape ( tx ) ; }
creates a speech bubble - shaped shape .
