// TAlphaComposite.java import java.awt.*; import java.awt.event.*; import java.awt.font.*; import java.awt.geom.*; import java.awt.image.*; import javax.swing.*; import javax.swing.event.*; class TAlphaComposite extends JFrame { DrawingCanvas canvas; JSlider slider, sliderAlpha; JComboBox rulesBox; // Labels for Porter Duff Rules, and the corresponding fields in // the class AlphaComposite. String[] rulesLabels = {"Clear", "Source", "Source-over", "Destination-over", "Source-in", "Destination-in", "Source-out", "Destination-out"}; int[] rules = {AlphaComposite.CLEAR, AlphaComposite.SRC, AlphaComposite.SRC_OVER, AlphaComposite.DST_OVER, AlphaComposite.SRC_IN, AlphaComposite.DST_IN, AlphaComposite.SRC_OUT, AlphaComposite.DST_OUT}; public TAlphaComposite() { // 1. Assign a name to the frame, and obtain its // content pane. super("TAlphaComposite"); Container container = getContentPane(); // 2. Create a canvas and add it to the frame canvas = new DrawingCanvas(); container.add(canvas); // 3. Create a rules combo box, and alpha adjustment slider // in a panel, and add them panel to the frame. rulesBox = new JComboBox(rulesLabels); rulesBox.setSelectedIndex(0); rulesBox.setAlignmentX(Component.LEFT_ALIGNMENT); rulesBox.addActionListener(new ComboBoxListener()); setSlider(0, 100, 100, 25, 5); sliderAlpha = slider; JPanel panel = new JPanel(); panel.setLayout(new GridLayout(1,3)); panel.add(rulesBox); panel.add(new JLabel("Alpha Adjustment x E-2: ", JLabel.RIGHT)); panel.add(sliderAlpha); container.add(panel, BorderLayout.SOUTH); // 4. Add a window closing listener and display it a suitable size addWindowListener(new WindowEventHandler()); pack(); show(); } // 5. Code to handle the closing of frame class WindowEventHandler extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } // 6. Method to create sliders with necessary configuration public void setSlider(int min, int max, int init, int mjrTkSp, int mnrTkSp) { slider = new JSlider(JSlider.HORIZONTAL, min, max, init); slider.setPaintTicks(true); slider.setMajorTickSpacing(mjrTkSp); slider.setMinorTickSpacing(mnrTkSp); slider.setPaintLabels(true); slider.addChangeListener(new SliderListener()); } // 7. The main method... public static void main(String arg[]) { new TAlphaComposite(); } // 8. Slider listener class class SliderListener implements ChangeListener { public void stateChanged(ChangeEvent e) { JSlider slider = (JSlider) e.getSource(); canvas.alphaValue = (float) slider.getValue()/100; canvas.repaint(); } } // 9. Combo box listener class class ComboBoxListener implements ActionListener { public void actionPerformed(ActionEvent e) { JComboBox cb = (JComboBox) e.getSource(); canvas.compositeRule = rules[cb.getSelectedIndex()]; canvas.repaint(); } } } // 10. Canvas to paint the overlapped ellipses class DrawingCanvas extends Canvas { float alphaValue = 1.0f; int compositeRule = AlphaComposite.CLEAR; AlphaComposite ac; DrawingCanvas() { setSize(300, 300); setBackground(Color.white); } public void paint(Graphics g) { // 11. Set up the 2D graphics context Graphics2D g2D = (Graphics2D) g; // 12. Retrieve the size of the canvas int w = getSize().width; int h = getSize().height; // 13. Create a buffered image and obtain its graphics context BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); Graphics2D big = bi.createGraphics(); // 14. Define an alpha composite instance with the selected composite // rule and the alpha value. ac = AlphaComposite.getInstance(compositeRule, alphaValue); // 15. Create two overlapped ellipses with red and blue colors // Draw the destination ellipse in red color. big.setColor(Color.red); big.drawString("Destination", w/4, h/4); big.fill(new Ellipse2D.Double(0, h/3, 2*w/3, h/3)); // Draw the source ellipse in blue color. big.setColor(Color.blue); big.drawString("Source", 3*w/4, h/4); // 16. Assign the composite object to the graphics context big.setComposite(ac); big.fill(new Ellipse2D.Double(w/3, h/3, 2*w/3, h/3)); // 17. Finally display the buffered image. g2D.drawImage(bi, null, 0, 0); } }