I've been working on a program that involves the rotation of a partially transparent image over a transparent form. The drawing of the image originally worked fine, I also set my custom panel's background color to a transparent light blue this worked fine as well. My problems started when I tried rotating my image.
In order to rotate it I had to convert the panel.getGraphics() over to a Graphics2D. When I did this the transparency went away, So I finished up on my rotation code and then read up on transparency. I found that I could set the composite of the Graphics2D and that is exactly what I did as seen here:
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC));
g2d.setColor(new Color(0, 0, 200, 90));
g2d.fillRect(0, 0, this.getWidth(), this.getHeight());
g2d.rotate(radians);
g2d.drawImage(img, 0, 0, null);
repaint();
}
When I run this I get the form as follows (Please note that this is not my normal image):
This is almost what I want except for it doesn't show the transparent blue background. However if I rotate the image the blue shows:
Problem is partially in the composite you specify: AlphaComposite.SRC
I don't really know what for did you use it but it overwrites source pixels data. That is why panel background gets overwrited when image is painted over it.
I suggest you to read about composite in graphics if you didn't read it yet: http://docs.oracle.com/javase/tutorial/2d/advanced/compositing.html
Anyway, see the example how something similar could be done:
(this is just one of possibilities - you could do it in ten other ways)
public class SmileyTest
{
private static Color bg = new Color ( 0, 0, 255, 128 );
private static float angle = 0f;
public static void main ( String[] args )
{
final ImageIcon icon = new ImageIcon ( SmileyTest.class.getResource ( "icons/smiley.png" ) );
JDialog frame = new JDialog ();
frame.setLayout ( new BorderLayout () );
// We should not use default background and opaque panel - that might cause repaint problems
// This is why we use JPanel with transparent background painted and opacity set to false
JPanel transparentPanel = new JPanel ( new BorderLayout () )
{
protected void paintComponent ( Graphics g )
{
super.paintComponent ( g );
g.setColor ( bg );
g.fillRect ( 0, 0, getWidth (), getHeight () );
}
};
transparentPanel.setOpaque ( false );
frame.add ( transparentPanel );
// Image in another component
final JComponent component = new JComponent ()
{
protected void paintComponent ( Graphics g )
{
super.paintComponent ( g );
Graphics2D g2d = ( Graphics2D ) g;
// For better image quality when it is rotated
g2d.setRenderingHint ( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR );
// Rotating area using image middle as rotation center
g2d.rotate ( angle * Math.PI / 180, getWidth () / 2, getHeight () / 2 );
// Transparency for image
g2d.setComposite ( AlphaComposite.getInstance ( AlphaComposite.SRC_OVER, 0.5f ) );
// Draing image
g2d.drawImage ( icon.getImage (), 0, 0, null );
}
};
transparentPanel.add ( component );
// Rotation animation (24 frames per second)
new Timer ( 1000 / 48, new ActionListener ()
{
public void actionPerformed ( ActionEvent e )
{
angle += 0.5f;
component.repaint ();
}
} ).start ();
frame.setUndecorated ( true );
AWTUtilities.setWindowOpaque ( frame, false );
frame.setSize ( icon.getIconWidth (), icon.getIconHeight () );
frame.setLocationRelativeTo ( null );
frame.setVisible ( true );
}
}
Just run this and see the result:
There are also a few comments over the code why you should or shouldn't do something.
Make sure you read them carefully.