Cambiando el punteado y los atributos de dibujo en el contexto de Graphics2D, antes del dibujo, podemos f�cilmente aplicar estilos divertidos de l�neas y patrones de relleno para gr�ficos primitivos. Por ejemplo, podemos dibujar una l�nea punteada creando el objeto Stroke apropiado y llamando a setStroke para a�adirlo al contexto Graphics2D antes de dibujar la l�nea. De forma similar, podemos aplicar un relleno de gradiente a un Shape creando un objeto GradientPaint y a�adiendo al contexto Graphics2D llamando a setPaint antes de dibujar la Shape.
El siguiente applet demuestra c�mo podemos dibujar formas geom�tricas usando los m�todos
Graphics2D draw y fill.
Esta es una imagen del GUI del applet. Para ajecutar el applet, pulsa sobre ella. El applet aparecer� en una nueva ventana del navegador.
ShapesDemo2D.java contiene el c�digo completo de este applet.
Cada una de las formas dibujadas por el applet est� construida de geometr�as y est� dibujada a trav�s de Graphics2D. Las variables rectHeight y rectWidth de este ejemplo definen las dimensiones del espacio en que se dibuja cada forma, en pixels. La variables x e y cambian para cada forma para que sean dibujadas en formaci�n de parrilla.
�![]() |
// draw Line2D.Double g2.draw(new Line2D.Double(x, y+rectHeight-1, x + rectWidth, y)); |
�![]() |
// draw Rectangle2D.Double g2.setStroke(stroke); g2.draw(new Rectangle2D.Double(x, y, rectWidth, rectHeight)); |
�![]() |
// draw RoundRectangle2D.Double g2.setStroke(dashed); g2.draw(new RoundRectangle2D.Double(x, y, rectWidth, rectHeight, 10, 10)); |
�![]() |
// draw Arc2D.Double g2.setStroke(wideStroke); g2.draw(new Arc2D.Double(x, y, rectWidth, rectHeight, 90, 135, Arc2D.OPEN)); |
�![]() |
// draw Ellipse2D.Double g2.setStroke(stroke); g2.draw(new Ellipse2D.Double(x, y, rectWidth, rectHeight)); |
�![]() |
// draw GeneralPath (polygon) int x1Points[] = {x, x+rectWidth, x, x+rectWidth}; int y1Points[] = {y, y+rectHeight, y+rectHeight, y}; GeneralPath polygon = new GeneralPath(GeneralPath.WIND_EVEN_ODD, x1Points.length); polygon.moveTo(x1Points[0], y1Points[0]); for (int index = 1; index < x1Points.length; index++) { polygon.lineTo(x1Points[index], y1Points[index]); }; polygon.closePath(); g2.draw(polygon); |
�![]() |
// draw GeneralPath (polyline) int x2Points[] = {x, x+rectWidth, x, x+rectWidth}; int y2Points[] = {y, y+rectHeight, y+rectHeight, y}; GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, x2Points.length); polyline.moveTo (x2Points[0], y2Points[0]); for (int index = 1; index < x2Points.length; index++) { polyline.lineTo(x2Points[index], y2Points[index]); }; g2.draw(polyline); |
�![]() |
// fill Rectangle2D.Double (red) g2.setPaint(red); g2.fill(new Rectangle2D.Double(x, y, rectWidth, rectHeight)); |
�![]() |
// fill RoundRectangle2D.Double g2.setPaint(redtowhite); g2.fill(new RoundRectangle2D.Double(x, y, rectWidth, rectHeight, 10, 10)); |
�![]() |
// fill Arc2D g2.setPaint(red); g2.fill(new Arc2D.Double(x, y, rectWidth, rectHeight, 90, 135, Arc2D.OPEN)); |
�![]() |
// fill Ellipse2D.Double g2.setPaint(redtowhite); g2.fill (new Ellipse2D.Double(x, y, rectWidth, rectHeight)); |
�![]() |
// fill and stroke GeneralPath int x3Points[] = {x, x+rectWidth, x, x+rectWidth}; int y3Points[] = {y, y+rectHeight, y+rectHeight, y}; GeneralPath filledPolygon = new GeneralPath(GeneralPath.WIND_EVEN_ODD, x3Points.length); filledPolygon.moveTo(x3Points[0], y3Points[0]); for (int index = 1; index < x3Points.length; index++) { filledPolygon.lineTo(x3Points[index], y3Points[index]); }; filledPolygon.closePath(); g2.setPaint(red); g2.fill(filledPolygon); |
Observa que este ejemplo usa implementaciones de doble precision de las clases geom�tricas. Donde sea posible, las implementaciones de los float y doble precisi�n de cada geom�trico est�n proporcionados por clases internas.
�Dibujar Curvas
Los applets Cubic y Quad demuestran como crear curvas c�bicas y cuadr�ticas usando CubicCurve2D y QuadCurve2D. Estos applets tambi�n demuestran como se dibujan las curvas con respecto al posicionamiento de los puntos de control permitiendonos mover interactivamente tanto los puntos de control como los puntos finales.
�Ejemplo: Quad
El applet Quad demuestra una curva cuadr�tica, que es un segmento de
curva que tiene dos puntos finales y un �nico punto de control. El punto de control
determina la forma de la curva controlando tanto el punto de control como los vectores
tangenciales de los puntos finales.
Esta es una imagen del GUI del applet. Para ajecutar el applet, pulsa sobre ella. El applet aparecer� en una nueva ventana del navegador.
Quad.java contiene el c�digo completo de este applet.
Primero se crea una nueva curva cuadr�tica con dos puntos finales y un punto de control y las posiciones de los puntos se seleccionan con respecto al tama�o de la ventana.
QuadCurve2D.Double quad = new QuadCurve2D.Double(); Point2D.Double start, end, control; start = new Point2D.Double(); one = new Point2D.Double(); control = new Point2D.Double(); quad.setCurve(start, one, control); start.setLocation(w/2-50, h/2); end.setLocation(w/2+50, h/2); control.setLocation((int)(start.x)+50, (int)(start.y)-50);
Cada vez que el usuario mueva uno de los puntos, la curva se resetear�.
quad.setCurve(start, control, end);
�Ejemplo: Cubic
El ejemplo Cubic muestra una curva c�bica, que es un segmento de
curva que tiene dos puntos finales y dos puntos de control. Cada punto de control
determina la forma de la curva mediante el control de uno de los vectores tangenciales de
un punto final. En el ejemplo Cubic, las cruces coloreadas se
dibujan donde se encuentran los puntos de control y los puntos finales. El punto de
control azul controla el punto final rojo y el punto de control verde controla el punto
final magenta.
Esta es una imagen del GUI del applet. Para ajecutar el applet, pulsa sobre ella. El applet aparecer� en una nueva ventana del navegador.
Cubic.java contiene el c�digo completo de este applet.
Una curva c�bica se crea con dos puntos finales y dos puntos de control y las localizaciones de los puntos se seleccionan con respecto al tama�o de la ventana.
CubicCurve2D.Double cubic = new CubicCurve2D.Double(); Point2D.Double start, end, one, two; start = new Point2D.Double(); one = new Point2D.Double(); two = new Point2D.Double(); end = new Point2D.Double(); cubic.setCurve(start, one, two, end); ... start.setLocation(w/2-50, h/2); end.setLocation(w/2+50, h/2); one.setLocation((int)(start.x)+25, (int)(start.y)-25); two.setLocation((int)(end.x)-25, (int)(end.y)+25);
Como en el ejemplo Quad, la curva es reseteada cada vez que se mueven los puntos.
cubic.setCurve(start, one, two, end);
�Dibujar formas arbitrarias
El ejemplo ShapesDemo usa GeneralPath para hacer pol�gonos en forma de cristales, pero tambien podemos usar GeneralPath para hacer formas arbitrarias tanto con l�neas rectas como curvas.
�Ejemplo: Odd_Shape
El ejemplo Odd_Shape usa GeneralPath para crear
formas arbitrarias en la secci�n
Formas.
Esta es una imagen del GUI del applet. Para ajecutar el applet, pulsa sobre ella. El applet aparecer� en una nueva ventana del navegador.
Odd_Shape.java contiene el c�digo completo de este applet.
El siguiente c�digo crea un nuevo GeneralPath y a�ade el primer punto al path.
GeneralPath oddShape = new GeneralPath(); ... x = w/2 + 50; y = h/2 - 25; x2 = x; y2 = y; oddShape.moveTo(x, y);
Despu�s de a�adir el primer punto al path, se a�aden tres l�neas rectas.
x -= 100; oddShape.lineTo(x, y); y += 50; oddShape.lineTo(x, y); x += 100; oddShape.lineTo(x, y);
Finalmente, se a�ade una curva c�bica.
x += 10; y -= 10; x1 = x - 20; y1 = y - 20; oddShape.curveTo(x, y, x1, y1, x2, y2);
�Definir Estilos de l�nea divertidos y Patrones de relleno.
Probablemente habr�s observado en el ejemplo anterior algunas de las formas tienen l�neas punteadas o est�n rellenas con gradientes de dos colores. Usando las clases Stroke y Paint de Java 2D, podemos f�cilmente definir estilos de l�nea divertidos y patrones de relleno.
�Estilos de L�nea
Los estilos de l�nea est�n definidos por el atributo stroke en el contexto Graphics2D. Para seleccionar el atributo stroke podemos crear un objeto BasicStroke y pasarlo dentro del m�todo Graphics2D setStroke.
Un objeto BasicStroke contiene informaci�n sobre la anchura de la l�nea, estilo de uniones, estilos finales, y estilo de punteado. Esta informaci�n se usa cuando se dibuja un Shape con el m�todo draw.
La anchura de l�nea es la longitud de la l�nea medida perpendicularmente a su trayectoria. La anchura de la l�nea se especificada como un valor float en las unidades de coordenadas de usuario, que es equivalente a 1/72 pulgadas cuando se utiliza la transformaci�n por defecto.
El estilo de uni�n es la decoraci�n que se aplica cuando se encuentran dos segmentos de l�nea. BasicStroke soporta tres estilos de uni�n:.
JOIN_BEVEL
JOIN_MITER
JOIN_ROUND
El estilo de finales es la decoraci�n que se aplica cuando un segmento de l�nea termina. BasicStroke soporta tres estilos de finalizaci�n:
CAP_BUTT
CAP_ROUND
CAP_SQUARE
El estilo de punteado define el patr�n de las secciones opacas y transparentes aplicadas a lo largo de la longitud de la l�nea. Este estilo est� definido por un array de punteado y una fase de punteado. El array de punteado define el patr�n de punteado. Los elementos alternativos en el array representan la longitud del punteado y el espacio entre punteados en unidades de coordenadas de usuario.. El elemento 0 representa el primer punteado, el elemento 1 el primer espacio, etc. La fase de punteado es un desplazamiento en el patr�n de punteado, tambi�n especificado en unidades de coordenadas de usuario. La fase de punteado indica que parte del patr�n de punteado se aplica al principio de la l�nea.
�Patr�n de Relleno
Los patrones de rellenos est�n definidos por el atributo paint en el contexto Graphics2D. Para seleccionar el atributo paint, se crea un ejemplar de un objeto que implemente el interface Paint y se pasa dentro del m�todo Graphics2D setPaint.
Tres clases implementan el interface Paint: Color, GradientPaint, y TexturePaint . GradientPaint y TexturePaint son nuevas en el JDK 1.2.
Para crear un GradientPaint, se especifica una posici�n inicial y un color y una posici�n final y otro color. El gradiente cambia proporcionalmente desde un color al otro a lo largo de la l�nea que conecta las dos posiciones.

El patr�n para una TexturePaint esta definido por un BufferedImage. Para crear un TexturePaint, se especifica una imagen que contiene el patr�n y un rect�ngulo que se usa para replicar y anclar el patr�n.

�Ejemplo: StrokeAndFill
El applet StrokeAndFill permite al usuario seleccionar un gr�fico
primitivo, un estilo de l�nea, un estilo de dibujo y o bien puntear el exterior del
objeto, rellenarlo con el dibujo seleccionado, o puntear el objeto en blanco y rellenar
el dibujo con el dibujo seleccionado.
Esta es una imagen del GUI del applet. Para ajecutar el applet, pulsa sobre ella. El applet aparecer� en una nueva ventana del navegador.
StrokeAndFill.java contiene el c�digo completo de este applet.
Los primitivos son inicializados e introducidos en un array de objetos Shape. El siguiente c�digo crea un Rectangle y un Ellipse2D.Double y los introduce en el array shapes.
shapes[0] = new Rectangle(0, 0, 100, 100); shapes[1] = new Ellipse2D.Double(0.0, 0.0, 100.0, 100.0);
Para crear un objeto Shape desde una cadena de texto, primero debemos crear un objeto TextLayout desde el texto de la cadena.
TextLayout textTl = new TextLayout("Text", new Font("Helvetica", 1, 96), new FontRenderContext(null, false, false));
Las siguientes l�neas transforman el TextLayout para que sea centrado en el origen y luego introduce el objeto Shape resultante de la llamda a getOutline dentro del array shapes.
AffineTransform textAt = new AffineTransform(); textAt.translate(0, (float)textTl.getBounds().getHeight()); shapes[2] = textTl.getOutline(textAt);
Podemos elegir un primitivo accediendo al �ndice apropiado dentro del array shapes.
Shape shape = shapes[Transform.primitive.getSelectedIndex()];
C�mo se realiza el dibujo dependen de las opciones elegidas.
- Cuando el usuario elige stroke, se llama a Graphics2D.draw para realizar el dibujo, Si se elige text como primitivo, las l�neas son recuperadas y el dibujo se hace con el m�todo draw.
- Cuando el usuario elige fill, se llama a Graphics2D.fill o Graphics2D.drawString para realizar el dibujado.
- Cuando el usuario elige stroke and fill, se llama a fill o drawString para rellenar el Shape, y luego se llama a draw para dibujar la l�nea exterior.
Nota:
Para rellenar y puntear un gr�fico primitivo, necesitamos hacer dos llamadas separadas a m�todos: fill o drawString para rellenar el interior, y draw para dibujar el exterior. |
Los tres estilos de l�nea usados en este ejemplo -- ancho, estrecho y punteado -- son ejemplares de BasicStroke.
// Sets the Stroke. ... case 0 : g2.setStroke(new BasicStroke(3.0f)); break; case 1 : g2.setStroke(new BasicStroke(8.0f)); break; case 2 : float dash[] = {10.0f}; g2.setStroke(new BasicStroke(3.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f)); break;
El estilo de punteado de este ejemplo tiene 10 unidades de punteado alternados con 10 unidades de espacio. El principio del patr�n del punteado se aplica al principio de la l�nea -- la fase de punteado es 0.0.
En este ejemplo se usan tres estilos de dibujo -- s�lido, gradiente y polka. El dibujo de color s�lido es un ejemplar de Color, el gradiente un ejemplar de GradientPaint, y el patr�n un ejemplar de TexturePaint.
// Sets the Paint. ... case 0 : g2.setPaint(Color.blue); break; case 1 : g2.setPaint(new GradientPaint(0, 0, Color.lightGray, w-250, h, Color.blue, false)); break; case 2 : BufferedImage bi = new BufferedImage(5, 5, BufferedImage.TYPE_INT_RGB); Graphics2D big = bi.createGraphics(); big.setColor(Color.blue); big.fillRect(0, 0, 5, 5); big.setColor(Color.lightGray); big.fillOval(0, 0, 5, 5); Rectangle r = new Rectangle(0,0,5,5); g2.setPaint(new TexturePaint(bi, r)); break;