/*
* Copyright (C) 2004 TiongHiang Lee
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Email: thlee@onemindsoft.org
*/
package org.onemind.swingweb.awt;
import java.applet.Applet;
import java.awt.*;
import java.util.HashSet;
import java.util.Iterator;
import javax.swing.*;
import org.onemind.awtbridge.peer.BridgeComponentPeer;
import org.onemind.swingweb.SwingWebContext;
import org.onemind.swingweb.image.EmptyImage;
import org.onemind.swingweb.util.SwingWebUtils;
/**
* A lightweight repaint manager that does not maintain dirty regions but just validating component as needed
* @author TiongHiang Lee (thlee@onemindsoft.org)
*/
public class SwingWebRepaintManager extends javax.swing.RepaintManager
{
private static final Rectangle DUMMY_RECT = new Rectangle(0, 0);
private static final Image DUMMY_IMAGE = new EmptyImage(null);
private static final Image VOLATILE_DUMMY_IMAGE = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleVolatileImage(1, 1);
private HashSet _invalidComponents;
private class ValidatingEvent extends AWTEvent implements ActiveEvent
{
public ValidatingEvent(Object source, int id)
{
super(source, id);
}
public void dispatch()
{
RepaintManager.currentManager((Component) getSource()).validateInvalidComponents();
}
}
/**
* {@inheritDoc}
*/
public void addDirtyRegion(JComponent c, int x, int y, int w, int h)
{
//do nothing
}
/**
* {@inheritDoc}
*/
public synchronized void addInvalidComponent(JComponent invalidComponent)
{
Component validateRoot = null;
Component c = invalidComponent;
while (c != null)
{
if (c instanceof CellRendererPane || c.getPeer() == null)
{//shortcut
return;
}
if (c instanceof JComponent && ((JComponent) c).isValidateRoot())
{
validateRoot = c;
}
c = c.getParent();
}
if (validateRoot == null)
{
return;
}
Component root = null;
c = validateRoot;
while (c != null)
{
if (!c.isVisible() || c.getPeer() == null)
{
return;
} else if ((c instanceof Window) || (c instanceof Applet))
{
root = c;
break;
}
c = c.getParent();
}
if (root == null)
{
return;
}
/* Lazily create the invalidateComponents vector and add the
* validateRoot if it's not there already. If this validateRoot
* is already in the vector, we're done.
*/
if (_invalidComponents == null)
{
_invalidComponents = new HashSet();
}
((BridgeComponentPeer) validateRoot.getPeer()).setUpToDate(false);
_invalidComponents.add(validateRoot);
/* Queues a Runnable that calls RepaintManager.validateInvalidComponents()
* and RepaintManager.paintDirtyRegions() with SwingUtilities.invokeLater().
*/
SwingWebContext context = SwingWebUtils.getSwingWebContext();
context.getInputContext().getEventQueue().postEvent(new ValidatingEvent(root, 0));
}
/**
* {@inheritDoc}
*/
public Rectangle getDirtyRegion(JComponent aComponent)
{
return DUMMY_RECT;
}
/**
* {@inheritDoc}
*/
public Dimension getDoubleBufferMaximumSize()
{
// just pass
return super.getDoubleBufferMaximumSize();
}
/**
* {@inheritDoc}
*/
public Image getOffscreenBuffer(Component c, int proposedWidth, int proposedHeight)
{
return DUMMY_IMAGE;
}
/**
* {@inheritDoc}
*/
public void paintDirtyRegions()
{
//do nothing
}
/**
* {@inheritDoc}
*/
public Image getVolatileOffscreenBuffer(Component c, int proposedWidth, int proposedHeight)
{
return VOLATILE_DUMMY_IMAGE;
}
/**
* {@inheritDoc}
*/
public boolean isCompletelyDirty(JComponent aComponent)
{
//TODO: need to investigate
return false;
}
/**
* {@inheritDoc}
*/
public boolean isDoubleBufferingEnabled()
{
// just pass through
return false;
//return super.isDoubleBufferingEnabled();
}
/**
* {@inheritDoc}
*/
public void markCompletelyClean(JComponent aComponent)
{
//do nothing
}
/**
* {@inheritDoc}
*/
public void markCompletelyDirty(JComponent aComponent)
{
//do nothing;
}
/**
* {@inheritDoc}
*/
public synchronized void removeInvalidComponent(JComponent component)
{
_invalidComponents.remove(component);
}
/**
* {@inheritDoc}
*/
public void setDoubleBufferingEnabled(boolean aFlag)
{
super.setDoubleBufferingEnabled(aFlag);
}
/**
* {@inheritDoc}
*/
public void setDoubleBufferMaximumSize(Dimension d)
{
//do nothing
}
/**
* {@inheritDoc}
*/
public void validateInvalidComponents()
{
HashSet ic;
synchronized (this)
{
if (_invalidComponents == null)
{
return;
}
ic = _invalidComponents;
_invalidComponents = null;
}
Iterator it = ic.iterator();
while (it.hasNext())
{
((Component) it.next()).validate();
}
}
}