From the original question (below), I am now offering a bounty for the following:
An AlphaComposite based solution for rounded corners.
- Please demonstrate with a
JPanel. - Corners must be completely transparent.
- Must be able to support JPG painting, but still have rounded corners
- Must not use setClip (or any clipping)
- Must have decent performance
Hopefully someone picks this up quick, it seems easy.
I will also award the bounty if there is a well-explained reason why this can never be done, that others agree with.
Here is a sample image of what I have in mind (but usingAlphaComposite)
Original question
I’ve been trying to figure out a way to do rounded corners using compositing, very similar to How to make a rounded corner image in Java or http://weblogs.java.net/blog/campbell/archive/2006/07/java_2d_tricker.html.
However, my attempts without an intermediate BufferedImage don’t work – the rounded destination composite apparently doesn’t affect the source. I’ve tried different things but nothing works. Should be getting a rounded red rectangle, instead I’m getting a square one.
So, I have two questions, really:
1) Is there a way to make this work?
2) Will an intermediate image actually generate better performance?
SSCCE:
the test panel TPanel
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JLabel;
public class TPanel extends JLabel {
int w = 300;
int h = 200;
public TPanel() {
setOpaque(false);
setPreferredSize(new Dimension(w, h));
setMaximumSize(new Dimension(w, h));
setMinimumSize(new Dimension(w, h));
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
// Yellow is the clipped area.
g2d.setColor(Color.yellow);
g2d.fillRoundRect(0, 0, w, h, 20, 20);
g2d.setComposite(AlphaComposite.Src);
// Red simulates the image.
g2d.setColor(Color.red);
g2d.setComposite(AlphaComposite.SrcAtop);
g2d.fillRect(0, 0, w, h);
}
}
and its Sandbox
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JFrame;
public class Sandbox {
public static void main(String[] args) {
JFrame f = new JFrame();
f.setMinimumSize(new Dimension(800, 600));
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new FlowLayout());
TPanel pnl = new TPanel();
f.getContentPane().add(pnl);
f.setVisible(true);
}
}
With respect to your performance concerns the Java 2D Trickery article contains a link to a very good explanation by Chet Haase on the usage of Intermediate Images.
I think the following excerpt from O’Reilly’s Java Foundation Classes in a Nutshell could be helpful to you in order to make sense of the AlphaComposite behaviour and why intermediate images may be the necessary technique to use.