Stuck a final fork (I hope) in the repaint problems associated with popups

and other layered components.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1541 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2002-06-25 01:43:29 +00:00
parent 3d71bd858a
commit 9bffbc0b18
2 changed files with 52 additions and 21 deletions
+43 -19
View File
@@ -1,5 +1,5 @@
// //
// $Id: FrameManager.java,v 1.13 2002/06/21 03:43:59 mdb Exp $ // $Id: FrameManager.java,v 1.14 2002/06/25 01:43:29 mdb Exp $
package com.threerings.media; package com.threerings.media;
@@ -281,7 +281,7 @@ public class FrameManager
// repaint any widgets that have declared there need to be // repaint any widgets that have declared there need to be
// repainted since the last tick // repainted since the last tick
_remgr.paintComponents(_bgfx); _remgr.paintComponents(_bgfx, this);
// we cache our frame's graphics object so that we can avoid // we cache our frame's graphics object so that we can avoid
// instantiating a new one on every tick // instantiating a new one on every tick
@@ -299,12 +299,29 @@ public class FrameManager
} while (_backimg.contentsLost()); } while (_backimg.contentsLost());
} }
/**
* Renders all components in all {@link JLayeredPane} layers that
* intersect the supplied bounds.
*/
protected void renderLayers (Graphics g, Component pcomp, Rectangle bounds,
boolean[] clipped)
{
JLayeredPane lpane =
JLayeredPane.getLayeredPaneAbove(pcomp);
if (lpane != null) {
renderLayer(g, bounds, lpane, clipped, JLayeredPane.PALETTE_LAYER);
renderLayer(g, bounds, lpane, clipped, JLayeredPane.MODAL_LAYER);
renderLayer(g, bounds, lpane, clipped, JLayeredPane.POPUP_LAYER);
renderLayer(g, bounds, lpane, clipped, JLayeredPane.DRAG_LAYER);
}
}
/** /**
* Renders all components in the specified layer of the supplied * Renders all components in the specified layer of the supplied
* layered pane that intersect the supplied bounds. * layered pane that intersect the supplied bounds.
*/ */
protected void renderLayer (Graphics g, Rectangle bounds, protected void renderLayer (Graphics g, Rectangle bounds, JLayeredPane pane,
JLayeredPane pane, Integer layer) boolean[] clipped, Integer layer)
{ {
// stop now if there are no components in that layer // stop now if there are no components in that layer
int ccount = pane.getComponentCountInLayer(layer.intValue()); int ccount = pane.getComponentCountInLayer(layer.intValue());
@@ -321,6 +338,15 @@ public class FrameManager
if (!_lbounds.intersects(bounds)) { if (!_lbounds.intersects(bounds)) {
continue; continue;
} }
// if the clipping region has not yet been set during this
// render pass, the time has come to do so
if (!_clipped[0]) {
g.setClip(bounds);
_clipped[0] = true;
}
// translate into the components coordinate system and render
g.translate(_lbounds.x, _lbounds.y); g.translate(_lbounds.x, _lbounds.y);
comp.paint(g); comp.paint(g);
g.translate(-_lbounds.x, -_lbounds.y); g.translate(-_lbounds.x, -_lbounds.y);
@@ -494,14 +520,13 @@ public class FrameManager
// get the bounds of this component // get the bounds of this component
pcomp.getBounds(_bounds); pcomp.getBounds(_bounds);
// the bounds adjustment we're about to call will add // the bounds adjustment we're about to call will add in the
// in the components initial bounds offsets, so we // components initial bounds offsets, so we remove them here
// remove them here
_bounds.setLocation(0, 0); _bounds.setLocation(0, 0);
// convert them into top-level coordinates; also note // convert them into top-level coordinates; also note that if
// that if this component does not have a valid or // this component does not have a valid or visible root, we
// visible root, we don't want to paint it either // don't want to paint it either
if (getRoot(pcomp, _bounds) == null) { if (getRoot(pcomp, _bounds) == null) {
return true; return true;
} }
@@ -524,15 +549,10 @@ public class FrameManager
Log.logStackTrace(t); Log.logStackTrace(t);
} }
// render any components in our layered pane that are // render any components in our layered pane that are not in
// not in the default layer (the clipping rectangle is // the default layer
// still set appropriately) _clipped[0] = false;
JLayeredPane lpane = renderLayers(_g, pcomp, _bounds, _clipped);
JLayeredPane.getLayeredPaneAbove(pcomp);
renderLayer(_g, _bounds, lpane, JLayeredPane.PALETTE_LAYER);
renderLayer(_g, _bounds, lpane, JLayeredPane.MODAL_LAYER);
renderLayer(_g, _bounds, lpane, JLayeredPane.POPUP_LAYER);
renderLayer(_g, _bounds, lpane, JLayeredPane.DRAG_LAYER);
return true; return true;
} }
@@ -578,6 +598,10 @@ public class FrameManager
* components. */ * components. */
protected Rectangle _lbounds = new Rectangle(); protected Rectangle _lbounds = new Rectangle();
/** Used to lazily set the clip when painting popups and other
* "layered" components. */
protected boolean[] _clipped = new boolean[1];
/** Used to queue up a call to {@link #tick} on the AWT thread. */ /** Used to queue up a call to {@link #tick} on the AWT thread. */
protected Runnable _callTick = new Runnable () { protected Runnable _callTick = new Runnable () {
public void run () { public void run () {
@@ -1,5 +1,5 @@
// //
// $Id: FrameRepaintManager.java,v 1.8 2002/06/10 21:31:56 shaper Exp $ // $Id: FrameRepaintManager.java,v 1.9 2002/06/25 01:43:29 mdb Exp $
package com.threerings.media; package com.threerings.media;
@@ -202,7 +202,7 @@ public class FrameRepaintManager extends RepaintManager
/** /**
* Paints the components that have become dirty since the last tick. * Paints the components that have become dirty since the last tick.
*/ */
public void paintComponents (Graphics g) public void paintComponents (Graphics g, FrameManager fmgr)
{ {
// swap out our hashmap // swap out our hashmap
synchronized (this) { synchronized (this) {
@@ -357,6 +357,10 @@ public class FrameRepaintManager extends RepaintManager
} }
g.translate(-_cbounds.x, -_cbounds.y); g.translate(-_cbounds.x, -_cbounds.y);
// we also need to repaint any components in this layer
// that are above our freshly repainted component
fmgr.renderLayers(g, ocomp, _cbounds, _clipped);
} else if (root != null) { } else if (root != null) {
if (DEBUG) { if (DEBUG) {
Log.info("Repainting old-school " + Log.info("Repainting old-school " +
@@ -429,6 +433,9 @@ public class FrameRepaintManager extends RepaintManager
/** Used to compute dirty components' bounds. */ /** Used to compute dirty components' bounds. */
protected Rectangle _cbounds = new Rectangle(); protected Rectangle _cbounds = new Rectangle();
/** Used when rendering "layered" components. */
protected boolean[] _clipped = new boolean[] { true };
/** We debug so much that we have to make it easy to enable and /** We debug so much that we have to make it easy to enable and
* disable debug logging. Yay! */ * disable debug logging. Yay! */
protected static final boolean DEBUG = false; protected static final boolean DEBUG = false;