Skip to main content

How can I lock panel without repaint all component.

7 replies [Last post]
averyanov
Offline
Joined: 2009-09-28

Hello!

If I use the standart glasspane than Swing will repaint entire frame.

Is it possible to lock frame with transparent panel but without invoke repaint all component.

I tried:

// the component to be locked
JPanel panel = getMyPanel();

LockableUI lockableUI = new LockableUI();
// wrap the panel with JXLayer and the lockableUI
JXLayer l = new JXLayer(panel, lockableUI);
// lock the layer
lockableUI.setLocked(true);

// add the layer as any other component
frame.add(l);

But all component will repaint too when I invoke setLocked(true);

Thanks.

Message was edited by: averyanov

Message was edited by: averyanov

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
fanguad
Offline
Joined: 2006-01-24

This reply is a long time in coming, but I finally got around to implementing this behavior, and your solution works great. I can jack the redraw rate way up and the CPU hardly blips.

(I'm actually using JLayer and JDK 7 now, but it's basically the same)

Message was edited by: fanguad

demotivator
Offline
Joined: 2007-11-12

This solved a performance issue for me using a BusyPainter with JXLayer and LockableUI. I was seeing high CPU consumption when the JXLayer was locked (locking a 1024x768 region or larger), but now it is using a trivial amount of CPU time.

I found that with only painting the small region with the BusyPainter I was seeing some paint artifacts that ruined the nice appearance of the effect. So, I added a buffered image of the region before painting the busy painter begins, and buffer the drawing of it and the busy painter effect (avoids flickering I saw without double buffering) before drawing on screen. The result works great for me:

protected void paintLayer(Graphics2D g2, JXLayer l) {
super.paintLayer(g2, l);
if (isLocked()) {
BufferedImage tempbuf = new BufferedImage(l.getWidth(), l.getHeight(),BufferedImage.TYPE_INT_RGB);
super.paintLayer((Graphics2D)tempbuf.getGraphics(),l);
buf.getGraphics().drawImage(tempbuf, 0,0,80,80, (l.getWidth() / 2) - 49, (l.getHeight() / 2) - 49, (l.getWidth() / 2 ) + 31, (l.getHeight() / 2) + 31, null);
width = l.getWidth();
height = l.getHeight();
busyPainter.paint(g2, l, width, height);
}
}

public void handlePropertyChangeEvent(PropertyChangeEvent evt, JXLayer l) {
if ("repaintHalf".equals(evt.getPropertyName())) {
if(l.isVisible()) {
Graphics2D g2 = (Graphics2D) l.getGraphics();
if (g2 != null && buf != null) {
g2.translate((l.getWidth() / 2) - 50, (l.getHeight() / 2) - 50);
buf2.getGraphics().drawImage(buf, 0,0,80,80,null);
busyPainter.paint((Graphics2D) buf2.getGraphics(), l, 80, 80);
g2.drawImage(buf2, null, 1, 1);
}
}
} else {
super.handlePropertyChangeEvent(evt, l);
}
}

Apologies for the formatting, couldn't figure out how to make that look right

alexfromsun
Offline
Joined: 2005-09-05

Hello demotivator

It's great to know you solved that problem

To enable auto-formatting please embrace the code snippet with the
[ code ] and [ /code ] tags with no spaces inside

Thanks
alexp

fanguad
Offline
Joined: 2006-01-24

I have a similar question. I have a JXLayer on top of a JPanel. I want to update a small portion of the JXLayer frequently - is it possible to set a clip region or something so I don't have to draw the whole JPanel every time?

alexfromsun
Offline
Joined: 2005-09-05

Hello Fanguad

This question means that you are doing something interesting with JXLayer!
:-)

Here is the best solution for the smart updating the latest version of JXLayer:
introduce a custom method for your LayerUI
that should repaint a part of the layer:

[code]
public void repaintHalfOfTheLayer() {
firePropertyChange("repaintHalf", null, null);
}[/code]

then override the handlePropertyChangeEvent:

[code]
public void handlePropertyChangeEvent(PropertyChangeEvent evt, JXLayer l) {
if("repaintHalf".equals(evt.getPropertyName())) {
l.repaint(0,0,l.getWidth()/2, getHeight()); // repaint half of every layer this ui is set to
} else {
super.handlePropertyChangeEvent(evt, l);
}
}[/code]

By the way, you are welcome to post here any pointers
to the applications that use JXLayer

Thanks
alexp

fanguad
Offline
Joined: 2006-01-24

It's my toy application, so it's not published anywhere. It's a small application for displaying the artwork/info from iTunes. The part where I'm using JXLayer is to draw a border around the outside of the application to track how much of the track has played, filling in like a progress bar. The alternative was drawing this progress bar directly on top of the artwork (which worked fine, but the code started to get a bit muddled - it's much cleaner with JXLayer). Because the JXLayer covers the whole window, the artwork has to get completely redrawn every time. If I try to decrease the refresh interval to 100ms or so, just redrawing the artwork starts to use significant system resources. Because 99% of the window remains constant, there's really no need for this.

I'll try your solution and let you know how it turns out.

alexfromsun
Offline
Joined: 2005-09-05

Hello Averyanov

It is impossible to show a "transparent" panel without repainting the underneath components,
they must be repainted because Swing doesn't know if the panel has any custom painting or not

Thanks
alexp