I've got a JButton which is painted using a custom UI delegate (CustomButtonUI extends BasicButtonUI). The CustomButtonUI's paint() method draws the button with rounded "antialiased" corners, to make the apperance as "smooth" as possible.
Somehow the "antialiased" edges of the button disappears each time i drag the mouse over the button. This makes the button edges look "pixelized". However, once I add a line of code to repaint the parent of the button, the antialiasing kicks in even when i drag the mouse over the button.
Now, my question relates to wether this is a good idea? I do after all repaint the parent component from a child component. I wonder if this lead to a loop of repaints? If the parent tries to repaint its children and the children tries to repaint its parent - then i assume we're talking about a loop.
I've attached my code as a reference. Any comments are very welcome!
public class JCustomButtonUI extends BasicButtonUI {
@Override
public void installUI(JComponent c) {
super.installUI(c);
AbstractButton b = (AbstractButton) c;
b.setBorderPainted(false);
}
@Override
public void paint(Graphics g, JComponent c) {
//Cast the Graphics instance to a Graphics2D instance.
Graphics2D g2d = (Graphics2D) g;
JButton b = (JButton) c;
//Repaint parent component to make sure that we get "antialiased"
//edges.
b.getParent().repaint();
//Get the component's height and width.
int w = (int) g.getClipBounds().getWidth();
int h = ((int) g.getClipBounds().getHeight());
//Make sure the button is drawn with "antialiased" edges.
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.GRAY);
g2d.fillRoundRect(0, 0, w, h, w, h);
}
}
Update 1
Just to illustrate the alias and antialiased border, please have a look at the below two pictures. When i (from the ButtonUI's paint() method) manually invoke the parent JPanel's repaint method, all borders are perfectly antialiased all the time. However, when i do not manually invoke the parent JPanel's repaint method, then the borders are no longer antialiased once i hoover the mouse over the button.
Update 2
I have shared the entire "component" which consists of a JPanel, a JSlider and a couple of JButtons on Snipt. Please get it from http://snipt.org/wnllg.
Update 3
It seems that i have managed to get it working. Instead of painting the JPanel's background in its paintComponent() method, i created a JCustomPanelUI which i installed on the JPanel. I don't think that was the solution itself, but instead of using width and height from the Graphics instance, I tried using widht and height from the JPanel itself. I'm not quite sure why things go wrong when i use width and height from the Graphics instance. I thought the width and height from the Graphics instance was already "prepared" with regard to dimensions from the JPanel component. You can have a look at the final component here: http://snipt.org/wnlli,
I've reduced the example to just the anti-aliasing, and I am unable to reproduce the problem. It doesn't appear to be platform dependent. I'm not sure why you are using
getClipBounds()
.Addendum:
I've update the example to use a gradient background behind a transparent button; I've put anti-aliased (left) and aliased (right) examples side-by-side. I see no unexpected behavior.