package com.sun.jna.examples; import java.awt.AlphaComposite; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.awt.Transparency; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JSlider; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; /** * Experiment with different compositing methods. Unfortunately you * can't use anything other than AlphaComposite on Graphics derived from * screen surface data. * * @author twall */ public class X11AlphaMaskTest { private static int alpha = 128; private static AlphaComposite composite = AlphaComposite.Src; public static void main(String[] args) { GraphicsConfiguration gc = WindowUtils.getAlphaCompatibleGraphicsConfiguration(); JFrame frame = new JFrame("X11 alpha test", gc); final JComponent content = new JComponent() { public Dimension getPreferredSize() { return new Dimension(100, 100); } private Color mix(Color c, int base) { float f = (float)alpha / 255; return new Color((int)(c.getRed() * f + base * (1 - f)), (int)(c.getGreen() * f + base * (1 - f)), (int)(c.getBlue() * f + base * (1 - f))); } protected void paintComponent(Graphics graphics) { BufferedImage buf = ((Graphics2D)graphics).getDeviceConfiguration(). createCompatibleImage(getWidth(), getHeight(), Transparency.TRANSLUCENT); Graphics2D g = buf.createGraphics(); g.setComposite(AlphaComposite.Clear); g.fillRect(0, 0, getWidth(), getHeight()); g.setComposite(AlphaComposite.SrcOver); int barw = getWidth() / 10; int barh = getHeight(); g.setColor(Color.red); g.fillRect(0, 0, barw, barh); g.setColor(new Color(255, 0, 0, alpha)); g.fillRect(barw, 0, barw, barh / 2); g.setColor(mix(Color.red, 255)); g.fillRect(barw, barh / 2, barw, barh / 4); g.setColor(mix(Color.red, 0)); g.fillRect(barw, barh *3 / 4, barw, barh / 4); g.setColor(Color.green); g.fillRect(2 * barw, 0, barw, barh); g.setColor(new Color(0, 255, 0, alpha)); g.fillRect(3 * barw, 0, barw, barh / 2); g.setColor(mix(Color.green, 255)); g.fillRect(3 * barw, barh / 2, barw, barh / 4); g.setColor(mix(Color.green, 0)); g.fillRect(3 * barw, barh *3 / 4, barw, barh / 4); g.setColor(Color.blue); g.fillRect(4 * barw, 0, barw, barh); g.setColor(new Color(0, 0, 255, alpha)); g.fillRect(5 * barw, 0, barw, barh / 2); g.setColor(mix(Color.blue, 255)); g.fillRect(5 * barw, barh / 2, barw, barh / 4); g.setColor(mix(Color.blue, 0)); g.fillRect(5 * barw, barh * 3 / 4, barw, barh / 4); g.setColor(Color.white); g.fillRect(6 * barw, 0, barw, barh); g.setColor(new Color(255, 255, 255, alpha)); g.fillRect(7 * barw, 0, barw, barh / 2); g.setColor(mix(Color.white, 255)); g.fillRect(7 * barw, barh / 2, barw, barh / 4); g.setColor(mix(Color.white, 0)); g.fillRect(7 * barw, barh * 3 / 4, barw, barh / 4); g.setColor(Color.black); g.fillRect(8 * barw, 0, barw, barh); g.setColor(new Color(0, 0, 0, alpha)); g.fillRect(9 * barw, 0, barw, barh / 2); g.setColor(mix(Color.black, 255)); g.fillRect(9 * barw, barh / 2, barw, barh / 4); g.setColor(mix(Color.black, 0)); g.fillRect(9 * barw, barh * 3 / 4, barw, barh / 4); // small bar on top, black 50% alpha g.setColor(new Color(0, 0, 0, 128)); g.fillRect(0, 0, getWidth(), barh / 10); if (false) { BufferedImage prealpha = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB_PRE); g = prealpha.createGraphics(); g.setComposite(AlphaComposite.Src); g.drawImage(buf, 0, 0, getWidth(), getHeight(), null); g = (Graphics2D)graphics.create(); g.setComposite(composite); g.drawImage(prealpha, 0, 0, getWidth(), getHeight(), null); } else { g = (Graphics2D)graphics.create(); g.setComposite(composite); g.drawImage(buf, 0, 0, getWidth(), getHeight(), null); } g.dispose(); } }; final JSlider slider = new JSlider(0, 255, 128); slider.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { if (!slider.getModel().getValueIsAdjusting()) { alpha = slider.getValue(); content.repaint(); } } }); AlphaComposite[] options = { AlphaComposite.Clear, AlphaComposite.Src, AlphaComposite.SrcOver, AlphaComposite.SrcAtop, AlphaComposite.SrcIn, AlphaComposite.SrcOut, AlphaComposite.Dst, AlphaComposite.DstOver, AlphaComposite.DstAtop, AlphaComposite.DstIn, AlphaComposite.DstOut, AlphaComposite.Xor, }; final JComboBox combo = new JComboBox(options); combo.setOpaque(true); combo.setSelectedItem(composite); combo.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { composite = (AlphaComposite)combo.getSelectedItem(); content.repaint(); } }); frame.getContentPane().add(content); frame.getContentPane().add(slider, BorderLayout.SOUTH); frame.getContentPane().add(combo, BorderLayout.NORTH); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); if (System.getProperty("os.name").startsWith("Windows")) WindowUtils.setWindowTransparent(frame, true); frame.setLocation(100, 100); frame.setVisible(true); } }