More repaint manager fixes. We're now behaving even more closely like
Swing would behave. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1296 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: FrameManager.java,v 1.2 2002/04/23 03:10:59 mdb Exp $
|
// $Id: FrameManager.java,v 1.3 2002/04/27 02:33:14 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.media;
|
package com.threerings.media;
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ public class FrameManager
|
|||||||
_frame.setIgnoreRepaint(true);
|
_frame.setIgnoreRepaint(true);
|
||||||
|
|
||||||
// set up our custom repaint manager
|
// set up our custom repaint manager
|
||||||
_remgr = new FrameRepaintManager();
|
_remgr = new FrameRepaintManager(_frame);
|
||||||
RepaintManager.setCurrentManager(_remgr);
|
RepaintManager.setCurrentManager(_remgr);
|
||||||
|
|
||||||
// turn off double buffering for the whole business because we
|
// turn off double buffering for the whole business because we
|
||||||
@@ -324,7 +324,7 @@ public class FrameManager
|
|||||||
|
|
||||||
// // copy the off-screen buffer on-screen
|
// // copy the off-screen buffer on-screen
|
||||||
// fg.setClip(bounds);
|
// fg.setClip(bounds);
|
||||||
// fg.drawImage(_backimg, fi.left, fi.top, null);
|
// fg.drawImage(_backimg, 0, 0, null);
|
||||||
|
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
String ptos = StringUtil.safeToString(part);
|
String ptos = StringUtil.safeToString(part);
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
//
|
//
|
||||||
// $Id: FrameRepaintManager.java,v 1.1 2002/04/23 01:16:27 mdb Exp $
|
// $Id: FrameRepaintManager.java,v 1.2 2002/04/27 02:33:14 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.media;
|
package com.threerings.media;
|
||||||
|
|
||||||
import java.applet.Applet;
|
import java.applet.Applet;
|
||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
|
import java.awt.Frame;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Image;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.Window;
|
import java.awt.Window;
|
||||||
|
|
||||||
@@ -14,6 +16,7 @@ import javax.swing.CellRendererPane;
|
|||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.RepaintManager;
|
import javax.swing.RepaintManager;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@@ -30,6 +33,17 @@ import com.samskivert.util.StringUtil;
|
|||||||
*/
|
*/
|
||||||
public class FrameRepaintManager extends RepaintManager
|
public class FrameRepaintManager extends RepaintManager
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Components that are rooted in this frame will be rendered into the
|
||||||
|
* offscreen buffer managed by the frame manager. Other components
|
||||||
|
* will be rendered into separate offscreen buffers and repainted in
|
||||||
|
* the normal Swing manner.
|
||||||
|
*/
|
||||||
|
public FrameRepaintManager (Frame frame)
|
||||||
|
{
|
||||||
|
_rootFrame = frame;
|
||||||
|
}
|
||||||
|
|
||||||
// documentation inherited
|
// documentation inherited
|
||||||
public synchronized void addInvalidComponent (JComponent comp)
|
public synchronized void addInvalidComponent (JComponent comp)
|
||||||
{
|
{
|
||||||
@@ -126,7 +140,7 @@ public class FrameRepaintManager extends RepaintManager
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited
|
// documentation inherited
|
||||||
public synchronized Rectangle getDirtyRegion (JComponent comp)
|
public synchronized Rectangle getDirtyRegion (JComponent comp)
|
||||||
{
|
{
|
||||||
@@ -191,28 +205,44 @@ public class FrameRepaintManager extends RepaintManager
|
|||||||
Entry entry = (Entry)iter.next();
|
Entry entry = (Entry)iter.next();
|
||||||
JComponent comp = (JComponent)entry.getKey();
|
JComponent comp = (JComponent)entry.getKey();
|
||||||
Rectangle drect = (Rectangle)entry.getValue();
|
Rectangle drect = (Rectangle)entry.getValue();
|
||||||
Rectangle orect = (Rectangle)drect.clone();
|
|
||||||
Component root = FrameManager.getRoot(comp, drect);
|
|
||||||
|
|
||||||
Rectangle cbounds =
|
// get the root component, adjust the clipping (dirty)
|
||||||
new Rectangle(0, 0, comp.getWidth(), comp.getHeight());
|
// rectangle and obtain the bounds of the client in absolute
|
||||||
Rectangle obounds = comp.getBounds();
|
// coordinates
|
||||||
FrameManager.getRoot(comp, cbounds);
|
Component root = getRoot(comp, drect, _cbounds);
|
||||||
|
|
||||||
Rectangle clip = drect.intersection(cbounds);
|
// if this component is rooted in our frame, repaint it into
|
||||||
|
// the supplied graphics instance
|
||||||
if (root != null) {
|
if (root == _rootFrame) {
|
||||||
// if (!(comp instanceof JButton)) {
|
|
||||||
// Log.info("Repainting [comp=" + comp.getClass().getName() +
|
// Log.info("Repainting [comp=" + comp.getClass().getName() +
|
||||||
// StringUtil.toString(obounds) +
|
// StringUtil.toString(_cbounds) +
|
||||||
// StringUtil.toString(cbounds) +
|
// ", drect=" + StringUtil.toString(drect) + "].");
|
||||||
// ", root=" + root.getClass().getName() +
|
g.setClip(drect);
|
||||||
// ", clip=" + StringUtil.toString(clip) +
|
g.translate(_cbounds.x, _cbounds.y);
|
||||||
// ", drect=" + StringUtil.toString(drect) +
|
comp.paint(g);
|
||||||
// ", orect=" + StringUtil.toString(orect) + "].");
|
g.translate(-_cbounds.x, -_cbounds.y);
|
||||||
// }
|
|
||||||
g.setClip(clip);
|
} else if (root != null) {
|
||||||
root.paint(g);
|
// Log.info("Repainting old-school " +
|
||||||
|
// "[comp=" + comp.getClass().getName() + "].");
|
||||||
|
// otherwise, repaint with standard swing double buffers
|
||||||
|
Image obuf = getOffscreenBuffer(
|
||||||
|
comp, _cbounds.width, _cbounds.height);
|
||||||
|
Graphics og = null, cg = null;
|
||||||
|
try {
|
||||||
|
og = obuf.getGraphics();
|
||||||
|
comp.paint(og);
|
||||||
|
cg = comp.getGraphics();
|
||||||
|
cg.drawImage(obuf, 0, 0, null);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
if (og != null) {
|
||||||
|
og.dispose();
|
||||||
|
}
|
||||||
|
if (cg != null) {
|
||||||
|
cg.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,6 +250,57 @@ public class FrameRepaintManager extends RepaintManager
|
|||||||
_spare.clear();
|
_spare.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locates the root component for the supplied component, translates
|
||||||
|
* the supplied dirty rectangle into the root components' coordinate
|
||||||
|
* system and fills in the component's bounds in the root coordinate
|
||||||
|
* system.
|
||||||
|
*/
|
||||||
|
protected Component getRoot (JComponent comp, Rectangle dirty,
|
||||||
|
Rectangle bounds)
|
||||||
|
{
|
||||||
|
boolean debug = false;
|
||||||
|
|
||||||
|
// start with the component's untranslated bounds
|
||||||
|
bounds.setBounds(0, 0, comp.getWidth(), comp.getHeight());
|
||||||
|
|
||||||
|
for (Component c = comp; c != null; c = c.getParent()) {
|
||||||
|
if (!c.isVisible() || c.getPeer() == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(c instanceof JComponent)) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
Log.info("Adjusting " + c.getClass().getName() + " " +
|
||||||
|
c.getX() + ", " + c.getY() + ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
// adjust our coordinates
|
||||||
|
dirty.x += c.getX();
|
||||||
|
dirty.y += c.getY();
|
||||||
|
bounds.x += c.getX();
|
||||||
|
bounds.y += c.getY();
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
Log.info("Intersecting " + c.getBounds() + " and " +
|
||||||
|
dirty + ".");
|
||||||
|
}
|
||||||
|
SwingUtilities.computeIntersection(
|
||||||
|
c.getX(), c.getY(), c.getWidth(), c.getHeight(), dirty);
|
||||||
|
if (debug) {
|
||||||
|
Log.info("Intersected " + dirty + ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The managed frame. */
|
||||||
|
protected Frame _rootFrame;
|
||||||
|
|
||||||
/** A list of invalid components. */
|
/** A list of invalid components. */
|
||||||
protected Object[] _invalid;
|
protected Object[] _invalid;
|
||||||
|
|
||||||
@@ -229,4 +310,7 @@ public class FrameRepaintManager extends RepaintManager
|
|||||||
/** A spare hashmap that we swap in while repainting dirty components
|
/** A spare hashmap that we swap in while repainting dirty components
|
||||||
* in the old hashmap. */
|
* in the old hashmap. */
|
||||||
protected HashMap _spare = new HashMap();
|
protected HashMap _spare = new HashMap();
|
||||||
|
|
||||||
|
/** Used to compute dirty components' bounds. */
|
||||||
|
protected Rectangle _cbounds = new Rectangle();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user