Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Custom JPanel that clips children?

109 views
Skip to first unread message

Arabella

unread,
Aug 26, 2005, 3:15:58 PM8/26/05
to
I'm trying to implement a JPanel with rounded corners that clips it's
children so they don't run outside the jpanel's (now rounded) corners.

I'm able to clip the JPanel, but the children keep painting outside the
jpanel parent.

Do I have to override the paint routines of every child, or is there a way
for a parent to clip children?

I tried overriding every paint method I could find, I even tried commenting
out the contents of every paint, repaint, print, update, etc method and the
child is still leaving artifacts outside the parent.

-A


Thomas Hawtin

unread,
Aug 26, 2005, 4:02:30 PM8/26/05
to

I'd expect paintChildren to work. You should be able to trace back where
the child components are painted from. For instance using
Thread.dumpStack(); is you are not using a debugger. You should be able
to see what is happening in each method.

Some Swing painting erroneously uses setClip which will clear any user
clipping region. It's difficult to get screen corruption without
disabling double buffering, but it'll ignore your clipping region.

Tom Hawtin
--
Unemployed English Java programmer
http://jroller.com/page/tackline/

Christian Kaufhold

unread,
Aug 27, 2005, 5:15:06 PM8/27/05
to
Arabella <A...@not.here> wrote:

> I'm trying to implement a JPanel with rounded corners that clips it's
> children so they don't run outside the jpanel's (now rounded) corners.
>
> I'm able to clip the JPanel, but the children keep painting outside the
> jpanel parent.
>
> Do I have to override the paint routines of every child, or is there a way
> for a parent to clip children?

1. clipping in paintChildren.
2. making sure paintChildren is called on the panel and the children are
not painted directly. In principle, there is a way to do (JComponent.isPaint
Origin), but this is package-private. The hack to do it anyway is to
- override isOptimizedDrawingEnabled to return false
- add a bogus component on top that covers every other child (at least
partially?)
This may affect paint performance, but probably not too much.

Try this: (a) clips children, (b) paint on top of the children.

import javax.swing.*;

import java.awt.*;


public class POC
extends JComponent
{
public POC()
{
add(new JComponent() { });
add(new JTextField("XXX 2301923 91283 ")
{
public boolean isValidateRoot()
{
return false;
}
});
}


public void doLayout()
{
getComponent(0).setBounds(0, 0, getWidth(), getHeight());

Dimension d = getComponent(1).getPreferredSize();

getComponent(1).setBounds(10, 10, d.width, d.height);
}

public Dimension getPreferredSize()
{
return new Dimension(400, 400);
}

public boolean isOptimizedDrawingEnabled()
{
return false;
}

protected void paintChildren(Graphics g)
{
Shape s = g.getClip();

{
g.clipRect(20, 20, getWidth() - 40, getHeight() - 40);
}
try
{
super.paintChildren(g);
}
finally
{
g.setClip(s);
}

g.setColor(Color.red);

Rectangle r = getComponent(1).getBounds();

g.fillRect(r.x + r.width / 2, r.y, r.width / 2, r.height / 2);
}


public static void main(String[] args)
{
POC p = new POC();

JFrame f = new JFrame();

f.getContentPane().add(p);

f.pack(); f.show();
}
}

Christian

Christian Kaufhold

unread,
Sep 1, 2005, 7:21:43 AM9/1/05
to
Christian Kaufhold <use...@chka.de> wrote:

> Arabella <A...@not.here> wrote:
>
>> I'm trying to implement a JPanel with rounded corners that clips it's
>> children so they don't run outside the jpanel's (now rounded) corners.
>>
>> I'm able to clip the JPanel, but the children keep painting outside the
>> jpanel parent.
>>
>> Do I have to override the paint routines of every child, or is there a way
>> for a parent to clip children?
>
> 1. clipping in paintChildren.
> 2. making sure paintChildren is called on the panel and the children are
> not painted directly. In principle, there is a way to do (JComponent.isPaint
> Origin), but this is package-private. The hack to do it anyway is to
> - override isOptimizedDrawingEnabled to return false
> - add a bogus component on top that covers every other child (at least
> partially?)
> This may affect paint performance, but probably not too much.

For clipping, you actually need this. For painting over the children,
you could (with the workaround) actually do the painting in the covering
component.


Christian

Christian Kaufhold

unread,
Nov 9, 2005, 11:22:58 AM11/9/05
to
I wrote:

>> 1. clipping in paintChildren.
>> 2. making sure paintChildren is called on the panel and the children are
>> not painted directly. In principle, there is a way to do (JComponent.isPaint
>> Origin), but this is package-private. The hack to do it anyway is to
>> - override isOptimizedDrawingEnabled to return false
>> - add a bogus component on top that covers every other child (at least
>> partially?)
>> This may affect paint performance, but probably not too much.

> For clipping, you actually need this. For painting over the children,
> you could (with the workaround) actually do the painting in the covering
> component.

Clipping avoid opaque children only works properly if you fill the region
were they would be painted by hand. I don't think this is a bug.

If anyone is seriously interested, I may clarify the details.


Christian

Christian Kaufhold

unread,
Nov 9, 2005, 3:29:28 PM11/9/05
to
I wrote:

>> 1. clipping in paintChildren.
>> 2. making sure paintChildren is called on the panel and the children are
>> not painted directly. In principle, there is a way to do (JComponent.isPaint
>> Origin), but this is package-private. The hack to do it anyway is to
>> - override isOptimizedDrawingEnabled to return false
>> - add a bogus component on top that covers every other child (at least
>> partially?)
>> This may affect paint performance, but probably not too much.

> For clipping, you actually need this. For painting over the children,
> you could (with the workaround) actually do the painting in the covering
> component.

Clipping away parts of opaque children only works properly if you fill the region
where they would have been painted by hand. I don't think this is a bug.

0 new messages