(FULL SOURCE CODE: ONLINE ONLY) AlphaCompositeRules.Java.
- By Vincent J. Hardy
- June 13, 2000
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
/**
* Illustrates the use of the AlphaComposite class by showing the output created
* with different settings for that class's constructors. The code shows the result
* for the different Porter-Duff composition rules, with different alpha values.
*
* This example uses offscreen rendering
*
* @author Vincent Hardy
* @version 1.0, 12/30/1998
*/
public class AlphaCompositeRules extends JComponent{
// List of each AlphaCompositeRule, using two different alpha values
static AlphaComposite alphaComposites[] = {
AlphaComposite.Clear,
AlphaComposite.getInstance(AlphaComposite.CLEAR, .5f),
AlphaComposite.DstIn,
AlphaComposite.getInstance(AlphaComposite.DST_IN, .5f),
AlphaComposite.DstOut,
AlphaComposite.getInstance(AlphaComposite.DST_OUT, .5f),
AlphaComposite.DstOver,
AlphaComposite.getInstance(AlphaComposite.DST_OVER, .5f),
AlphaComposite.Src,
AlphaComposite.getInstance(AlphaComposite.SRC, .5f),
AlphaComposite.SrcIn,
AlphaComposite.getInstance(AlphaComposite.SRC_IN, .5f),
AlphaComposite.SrcOut,
AlphaComposite.getInstance(AlphaComposite.SRC_OUT, .5f),
AlphaComposite.SrcOver,
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .5f),
};
BufferedImage buf;
Shape blueDisc, redDisc;
Rectangle bounds;
public AlphaCompositeRules(){
redDisc = new Ellipse2D.Float(1, 2, 7, 7);
blueDisc = new Ellipse2D.Float(5, 2, 7, 7);
AffineTransform scale = AffineTransform.getScaleInstance(10, 10);
redDisc = scale.createTransformedShape(redDisc);
blueDisc = scale.createTransformedShape(blueDisc);
bounds = redDisc.getBounds();
bounds.add(blueDisc.getBounds());
bounds.width += 30;
bounds.height += 10;
buf = new BufferedImage((bounds.x + bounds.width)*2,
(bounds.y + bounds.height)*alphaComposites.length/2,
BufferedImage.TYPE_INT_ARGB_PRE);
Graphics2D g = buf.createGraphics();
setPreferredSize(new Dimension(buf.getWidth(), buf.getHeight()));
paintGraphics(g);
}
public Dimension getPreferredSize(){
return new Dimension(buf.getWidth(), buf.getHeight());
}
public void paintGraphics(Graphics2D g){
// g.scale(.25, .25);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//
// Iterate through the list of alphaComposites
//
Color red = new Color(200, 50, 50);
Color blue = new Color(50, 50, 120);
BufferedImage blueDiscBuf = new BufferedImage(bounds.x + bounds.width, bounds.y + bounds.height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = blueDiscBuf.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setPaint(blue);
g2.fill(blueDisc);
g2.dispose();
int nComposites = alphaComposites.length;
for(int i=0; i<nComposites; i++){
// Set default composite and paint a red square
g.setPaint(red);
g.setComposite(AlphaComposite.SrcOver);
g.fill(redDisc);
// Set current composite and blue paint
g.setPaint(blue);
g.setComposite(alphaComposites[i]);
g.fill(blueDisc);
// g.drawImage(blueDiscBuf, 0, 0, null);
if((i%2)==0)
g.translate(bounds.width, 0);
else
g.translate(-bounds.width, bounds.height);
}
}
/**
* Note the different behavior if you use the commented line
* instead of the offscreen buffer. The reason is that the
* offscreen buffer has an alpha channel.
*/
public void paint(Graphics _g){
// Use offscreen
_g.drawImage(buf, 0, 0, null);
// Alternate, direct rendering. Uncomment to see
// difference.
// paintGraphics((Graphics2D)_g);
}
public static void main(String args[]){
JFrame frame = new JFrame();
frame.getContentPane().add(new AlphaCompositeRules());
frame.getContentPane().setBackground(Color.white);
frame.pack();
frame.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent evt){
System.exit(0);
}
});
frame.setVisible(true);
}