Download this source file
// Logo2D.java - Demos Many 2D graphics effects. Note this
// Applet requires a Java 2 (version 1.4 or higher) JVM to run.
// This shows a fancy Java2D, internationalized logo.
// A special feature of this logo is the use of random numbers
// to control the appearence of the text.
//
// (C) 2003 by Wayne Pollock, Tampa FL USA. All Rights Reserved.
/*
<APPLET CODE="Logo2D" HEIGHT="250" WIDTH="400">
</APPLET>
*/
import java.applet.*;
import java.awt.*;
import java.awt.font.*; // For fancy text effects
import java.awt.geom.*; // Shapes to draw and fill
import java.util.Random; // New random number generator class
public class Logo2D extends Applet
{
long seed; // value for random number generator.
String logo, motto;
public void init ()
{
seed = new Random().nextLong();
setBackground( Color.pink );
logo = "Miracle Widgets";
motto = "It's a Miracle if it works well";
}
public void paint( Graphics gr )
{
Graphics2D g = (Graphics2D) gr;
Random rng = new Random( seed ); // create random number generator.
// Set the Font to something big:
Font mottoFont = new Font( "Serif", Font.BOLD, 18 );
Font logoFont = new Font( "Monospaced", Font.BOLD, 24 );
FontMetrics fm;
int hpos; // The left edge for drawing text
int ypos = 145; // The baseline for drawing motto text
// Draw simple text, centered:
g.setFont( mottoFont );
fm = g.getFontMetrics();
hpos = ( getWidth() - fm.stringWidth(motto) ) / 2;
g.drawString( motto, hpos, ypos );
ypos -= (fm.getHeight() + 5); // Place the logo above motto.
// Draw "fun" text. First convert a String into an array
// of "glyphs" which are Font-specific Shapes. Then before
// drawing any letter shape, apply some random transformations:
// Save original transformation and Paint:
AffineTransform originalTransform = g.getTransform();
Paint originalPaint = g.getPaint();
// Set initial drawing position for logo:
g.setFont( logoFont );
fm = g.getFontMetrics();
hpos = ( getWidth() - fm.stringWidth(logo) ) / 2;
g.translate( hpos, ypos );
// Create a GlyphVector (list of Shapes of letters):
FontRenderContext frc = g.getFontRenderContext();
GlyphVector gv = logoFont.createGlyphVector( frc, logo );
// Create a Transform to "jiggle" each letter shape a bit
// by small random scale, rotate, or shear transformations:
for ( int i = 0; i < gv.getNumGlyphs(); ++i )
{
// Create the transform to use to jiggle the letter:
AffineTransform at = new AffineTransform();
// Move ("translate") to position to draw the letter:
Point2D pos = gv.getGlyphPosition( i );
at.translate( pos.getX(), pos.getY() );
// Jiggle the letter:
switch ( rng.nextInt(4) )
{
case 0: // Apply a rotate transformation by +/- 10..20 degrees:
int sign = ( rng.nextInt( 2 ) == 0 ? -1 : 1 );
double angle = sign * (rng.nextDouble()/2.0 + 0.5) * Math.PI / 9.0;
at.rotate( angle );
break;
case 1: // Apply a scale traqnsformation:
// Stretch/shrink letter by +/- 50%:
double factor = (50 + rng.nextInt(100 + 1) ) / 100.0;
at.scale( factor, factor );
break;
case 2: // Apply a 25%..50% shear transformation in Y dimension only:
at.shear( ( 5 + rng.nextInt(6) ) / 20.0, 0.0 );
break;
default: // Don't transform (do nothing):
break;
}
// Set a random color to draw with:
Color [] colors = { Color.red, Color.orange.darker(), Color.blue,
Color.green.darker(), Color.darkGray, Color.magenta, Color.black
};
g.setPaint( colors[ rng.nextInt( colors.length ) ] );
// Draw the glyph: (The letter Shape is defined with (0,0) local to
// upper left of the glyphVector. As we have already used a translate
// transform (so as to apply the other transforms), if we just draw
// the Shapes they will all stack up on each other. The Shapes must
// be translated back to the correct positions. This could be done
// later using the Shape but Java 1.4 includes the method below,
// which allows use to easily reverse the original translation.
// (Prior to Java 1.4 each Shape in a GlyphVector had it's own
// (0,0) coordinate, so you would just use gv.getGlyphOutline(i).)
Shape letterShape = gv.getGlyphOutline( i, (float) -pos.getX(),
(float) -pos.getY() );
letterShape = at.createTransformedShape( letterShape );
g.fill( letterShape );
}
// Restore original graphic context:
g.setTransform( originalTransform );
g.setPaint( originalPaint );
// Draw a box using dashed lines and default Paint:
float [] dashList = {
5, // First a dash of 5 pixels
3, // then a 3 pixel gap
2, // then a 2 pixel dash
3 // a final 3 pixel gap before repeating
};
BasicStroke dashes = new BasicStroke(
2, // Line thickness
BasicStroke.CAP_ROUND, // Line end style
BasicStroke.JOIN_ROUND, // Line joint style
1, // Mitre join limit (joint extension)
dashList, // array of dash lengths
0 // Starting point of dashes
);
g.setStroke( dashes );
g.draw( new Rectangle(75, 70, 250, 95) );
// Draw a box using a thick diagonal rainbow line:
GradientPaint rainbow = new GradientPaint(
0, 0, Color.yellow, // Starting point and Color
20, 20, Color.blue, // Ending point and Color
true // Cycle through colors repeatedly
);
g.setPaint ( rainbow );
g.setStroke( new BasicStroke(10) ); // a 10 pel thick line
g.draw( new RoundRectangle2D.Double(30, 45, 340, 145, 5, 5) );
}
}