diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/javax/swing/JViewport.java | |
download | cbb-gcc-4.6.4-upstream.tar.bz2 cbb-gcc-4.6.4-upstream.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'libjava/classpath/javax/swing/JViewport.java')
-rw-r--r-- | libjava/classpath/javax/swing/JViewport.java | 948 |
1 files changed, 948 insertions, 0 deletions
diff --git a/libjava/classpath/javax/swing/JViewport.java b/libjava/classpath/javax/swing/JViewport.java new file mode 100644 index 000000000..729fac671 --- /dev/null +++ b/libjava/classpath/javax/swing/JViewport.java @@ -0,0 +1,948 @@ +/* JViewport.java -- + Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing; + +import gnu.classpath.SystemProperties; + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Insets; +import java.awt.LayoutManager; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.io.Serializable; + +import javax.accessibility.Accessible; +import javax.accessibility.AccessibleContext; +import javax.accessibility.AccessibleRole; +import javax.swing.border.Border; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.plaf.ViewportUI; + +/** + * + * <pre> + * _ + * +-------------------------------+ ...........Y1 \ + * | view | . \ + * | (this component's child) | . > VY + * | | . / = Y2-Y1 + * | +------------------------------+ ....Y2_/ + * | | viewport | | . + * | | (this component) | | . + * | | | | . + * | | | | . + * | | | | . + * | | | | . + * | +------------------------------+ ....Y3 + * | | . + * | . | . . + * | . | . . + * +---------.---------------------+ ...........Y4 + * . . . . + * . . . . + * . . . . + * X1.......X2.....................X3.......X4 + * \____ ___/ + * \/ + * VX = X2-X1 + *</pre> + * + * <p>A viewport is, like all swing components, located at some position in + * the swing component tree; that location is exactly the same as any other + * components: the viewport's "bounds".</p> + * + * <p>But in terms of drawing its child, the viewport thinks of itself as + * covering a particular position <em>of the view's coordinate space</em>. + * For example, the {@link #getViewPosition} method returns + * the position <code>(VX,VY)</code> shown above, which is an position in + * "view space", even though this is <em>implemented</em> by positioning + * the underlying child at position <code>(-VX,-VY)</code></p> + * + */ +public class JViewport extends JComponent implements Accessible +{ + /** + * Provides accessibility support for <code>JViewport</code>. + * + * @author Roman Kennke (roman@kennke.org) + */ + protected class AccessibleJViewport extends AccessibleJComponent + { + /** + * Creates a new instance of <code>AccessibleJViewport</code>. + */ + protected AccessibleJViewport() + { + // Nothing to do here. + } + + /** + * Returns the accessible role of <code>JViewport</code>, which is + * {@link AccessibleRole#VIEWPORT}. + * + * @return the accessible role of <code>JViewport</code> + */ + public AccessibleRole getAccessibleRole() + { + return AccessibleRole.VIEWPORT; + } + } + + /** + * A {@link java.awt.event.ComponentListener} that listens for + * changes of the view's size. This triggers a revalidate() call on the + * viewport. + */ + protected class ViewListener extends ComponentAdapter implements Serializable + { + private static final long serialVersionUID = -2812489404285958070L; + + /** + * Creates a new instance of ViewListener. + */ + protected ViewListener() + { + // Nothing to do here. + } + + /** + * Receives notification when a component (in this case: the view + * component) changes it's size. This simply triggers a revalidate() on the + * viewport. + * + * @param ev the ComponentEvent describing the change + */ + public void componentResized(ComponentEvent ev) + { + // Fire state change, because resizing the view means changing the + // extentSize. + fireStateChanged(); + revalidate(); + } + } + + public static final int SIMPLE_SCROLL_MODE = 0; + public static final int BLIT_SCROLL_MODE = 1; + public static final int BACKINGSTORE_SCROLL_MODE = 2; + + private static final long serialVersionUID = -6925142919680527970L; + + /** + * The default scrollmode to be used by all JViewports as determined by + * the system property gnu.javax.swing.JViewport.scrollMode. + */ + private static final int defaultScrollMode; + + protected boolean scrollUnderway; + protected boolean isViewSizeSet; + + /** + * This flag indicates whether we use a backing store for drawing. + * + * @deprecated since JDK 1.3 + */ + protected boolean backingStore; + + /** + * The backingstore image used for the backingstore and blit scroll methods. + */ + protected Image backingStoreImage; + + /** + * The position at which the view has been drawn the last time. This is used + * to determine the bittable area. + */ + protected Point lastPaintPosition; + + ChangeEvent changeEvent = new ChangeEvent(this); + + int scrollMode; + + /** + * The ViewListener instance. + */ + ViewListener viewListener; + + /** + * Stores the location from where to blit. This is a cached Point object used + * in blitting calculations. + */ + Point cachedBlitFrom; + + /** + * Stores the location where to blit to. This is a cached Point object used + * in blitting calculations. + */ + Point cachedBlitTo; + + /** + * Stores the width of the blitted area. This is a cached Dimension object + * used in blitting calculations. + */ + Dimension cachedBlitSize; + + /** + * Stores the bounds of the area that needs to be repainted. This is a cached + * Rectangle object used in blitting calculations. + */ + Rectangle cachedBlitPaint; + + boolean damaged = true; + + /** + * A flag indicating if the size of the viewport has changed since the + * last repaint. This is used in double buffered painting to check if we + * need a new double buffer, or can reuse the old one. + */ + boolean sizeChanged = true; + + /** + * Indicates if this JViewport is the paint root or not. If it is not, then + * we may not assume that the offscreen buffer still has the right content + * because parent components may have cleared the background already. + */ + private boolean isPaintRoot = false; + + /** + * Initializes the default setting for the scrollMode property. + */ + static + { + String scrollModeProp = + SystemProperties.getProperty("gnu.swing.scrollmode", "BACKINGSTORE"); + if (scrollModeProp.equalsIgnoreCase("simple")) + defaultScrollMode = SIMPLE_SCROLL_MODE; + else if (scrollModeProp.equalsIgnoreCase("backingstore")) + defaultScrollMode = BACKINGSTORE_SCROLL_MODE; + else + defaultScrollMode = BLIT_SCROLL_MODE; + } + + public JViewport() + { + setOpaque(true); + setScrollMode(defaultScrollMode); + updateUI(); + setLayout(createLayoutManager()); + lastPaintPosition = new Point(); + cachedBlitFrom = new Point(); + cachedBlitTo = new Point(); + cachedBlitSize = new Dimension(); + cachedBlitPaint = new Rectangle(); + } + + public Dimension getExtentSize() + { + return getSize(); + } + + public Dimension toViewCoordinates(Dimension size) + { + return size; + } + + public Point toViewCoordinates(Point p) + { + Point pos = getViewPosition(); + return new Point(p.x + pos.x, + p.y + pos.y); + } + + public void setExtentSize(Dimension newSize) + { + Dimension oldExtent = getExtentSize(); + if (! newSize.equals(oldExtent)) + { + setSize(newSize); + fireStateChanged(); + } + } + + /** + * Returns the viewSize when set, or the preferred size of the set + * Component view. If no viewSize and no Component view is set an + * empty Dimension is returned. + */ + public Dimension getViewSize() + { + Dimension size; + Component view = getView(); + if (view != null) + { + if (isViewSizeSet) + size = view.getSize(); + else + size = view.getPreferredSize(); + } + else + size = new Dimension(0, 0); + return size; + } + + + public void setViewSize(Dimension newSize) + { + Component view = getView(); + if (view != null) + { + if (! newSize.equals(view.getSize())) + { + scrollUnderway = false; + view.setSize(newSize); + isViewSizeSet = true; + fireStateChanged(); + } + } + } + + /** + * Get the viewport's position in view space. Despite confusing name, + * this really does return the viewport's (0,0) position in view space, + * not the view's position. + */ + + public Point getViewPosition() + { + Component view = getView(); + if (view == null) + return new Point(0,0); + else + { + Point p = view.getLocation(); + p.x = -p.x; + p.y = -p.y; + return p; + } + } + + public void setViewPosition(Point p) + { + Component view = getView(); + if (view != null && ! p.equals(getViewPosition())) + { + scrollUnderway = true; + view.setLocation(-p.x, -p.y); + fireStateChanged(); + } + } + + public Rectangle getViewRect() + { + return new Rectangle(getViewPosition(), getExtentSize()); + } + + /** + * @deprecated 1.4 + */ + public boolean isBackingStoreEnabled() + { + return scrollMode == BACKINGSTORE_SCROLL_MODE; + } + + /** + * @deprecated 1.4 + */ + public void setBackingStoreEnabled(boolean b) + { + if (b && scrollMode != BACKINGSTORE_SCROLL_MODE) + { + scrollMode = BACKINGSTORE_SCROLL_MODE; + fireStateChanged(); + } + } + + public void setScrollMode(int mode) + { + scrollMode = mode; + fireStateChanged(); + } + + public int getScrollMode() + { + return scrollMode; + } + + public Component getView() + { + if (getComponentCount() == 0) + return null; + + return getComponents()[0]; + } + + public void setView(Component v) + { + Component currView = getView(); + if (viewListener != null && currView != null) + currView.removeComponentListener(viewListener); + + if (v != null) + { + if (viewListener == null) + viewListener = createViewListener(); + v.addComponentListener(viewListener); + add(v); + fireStateChanged(); + } + revalidate(); + repaint(); + } + + public void reshape(int x, int y, int w, int h) + { + if (w != getWidth() || h != getHeight()) + sizeChanged = true; + super.reshape(x, y, w, h); + if (sizeChanged) + { + damaged = true; + fireStateChanged(); + } + } + + public final Insets getInsets() + { + return new Insets(0, 0, 0, 0); + } + + public final Insets getInsets(Insets insets) + { + if (insets == null) + return getInsets(); + insets.top = 0; + insets.bottom = 0; + insets.left = 0; + insets.right = 0; + return insets; + } + + + /** + * Overridden to return <code>false</code>, so the JViewport's paint method + * gets called instead of directly calling the children. This is necessary + * in order to get a useful clipping and translation on the children. + * + * @return <code>false</code> + */ + public boolean isOptimizedDrawingEnabled() + { + return false; + } + + public void paint(Graphics g) + { + Component view = getView(); + + if (view == null) + return; + + Rectangle viewBounds = view.getBounds(); + Rectangle portBounds = getBounds(); + + if (viewBounds.width == 0 + || viewBounds.height == 0 + || portBounds.width == 0 + || portBounds.height == 0) + return; + + switch (getScrollMode()) + { + + case JViewport.BACKINGSTORE_SCROLL_MODE: + paintBackingStore(g); + break; + case JViewport.BLIT_SCROLL_MODE: + paintBlit(g); + break; + case JViewport.SIMPLE_SCROLL_MODE: + default: + paintSimple(g); + break; + } + damaged = false; + } + + public void addChangeListener(ChangeListener listener) + { + listenerList.add(ChangeListener.class, listener); + } + + public void removeChangeListener(ChangeListener listener) + { + listenerList.remove(ChangeListener.class, listener); + } + + public ChangeListener[] getChangeListeners() + { + return (ChangeListener[]) getListeners(ChangeListener.class); + } + + /** + * This method returns the String ID of the UI class of Separator. + * + * @return The UI class' String ID. + */ + public String getUIClassID() + { + return "ViewportUI"; + } + + /** + * This method resets the UI used to the Look and Feel defaults.. + */ + public void updateUI() + { + setUI((ViewportUI) UIManager.getUI(this)); + } + + /** + * This method returns the viewport's UI delegate. + * + * @return The viewport's UI delegate. + */ + public ViewportUI getUI() + { + return (ViewportUI) ui; + } + + /** + * This method sets the viewport's UI delegate. + * + * @param ui The viewport's UI delegate. + */ + public void setUI(ViewportUI ui) + { + super.setUI(ui); + } + + public final void setBorder(Border border) + { + if (border != null) + throw new IllegalArgumentException(); + } + + /** + * Scrolls the view so that contentRect becomes visible. + * + * @param contentRect the rectangle to make visible within the view + */ + public void scrollRectToVisible(Rectangle contentRect) + { + Component view = getView(); + if (view == null) + return; + + Point pos = getViewPosition(); + // We get the contentRect in the viewport coordinates. But we want to + // calculate with view coordinates. + int contentX = contentRect.x + pos.x; + int contentY = contentRect.y + pos.y; + Rectangle viewBounds = getView().getBounds(); + Rectangle portBounds = getBounds(); + + if (isShowing()) + getView().validate(); + + // If the bottom boundary of contentRect is below the port + // boundaries, scroll up as necessary. + if (contentY + contentRect.height + viewBounds.y > portBounds.height) + pos.y = contentY + contentRect.height - portBounds.height; + // If contentY is above the port boundaries, scroll down to + // contentY. + if (contentY + viewBounds.y < 0) + pos.y = contentY; + // If the right boundary of contentRect is right from the port + // boundaries, scroll left as necessary. + if (contentX + contentRect.width + viewBounds.x > portBounds.width) + pos.x = contentX + contentRect.width - portBounds.width; + // If contentX is left from the port boundaries, scroll right to + // contentRect.x. + if (contentX + viewBounds.x < 0) + pos.x = contentX; + setViewPosition(pos); + } + + /** + * Returns the accessible context for this <code>JViewport</code>. This + * will be an instance of {@link AccessibleJViewport}. + * + * @return the accessible context for this <code>JViewport</code> + */ + public AccessibleContext getAccessibleContext() + { + if (accessibleContext == null) + accessibleContext = new AccessibleJViewport(); + return accessibleContext; + } + + /** + * Forward repaint to parent to make sure only one paint is performed by the + * RepaintManager. + * + * @param tm number of milliseconds to defer the repaint request + * @param x the X coordinate of the upper left corner of the dirty area + * @param y the Y coordinate of the upper left corner of the dirty area + * @param w the width of the dirty area + * @param h the height of the dirty area + */ + public void repaint(long tm, int x, int y, int w, int h) + { + Component parent = getParent(); + if (parent != null) + parent.repaint(tm, x + getX(), y + getY(), w, h); + else + super.repaint(tm, x, y, w, h); + } + + protected void addImpl(Component comp, Object constraints, int index) + { + if (getComponentCount() > 0) + remove(getComponents()[0]); + + super.addImpl(comp, constraints, index); + } + + protected void fireStateChanged() + { + ChangeListener[] listeners = getChangeListeners(); + for (int i = 0; i < listeners.length; ++i) + listeners[i].stateChanged(changeEvent); + } + + /** + * Creates a {@link ViewListener} that is supposed to listen for + * size changes on the view component. + * + * @return a ViewListener instance + */ + protected ViewListener createViewListener() + { + return new ViewListener(); + } + + /** + * Creates the LayoutManager that is used for this viewport. Override + * this method if you want to use a custom LayoutManager. + * + * @return a LayoutManager to use for this viewport + */ + protected LayoutManager createLayoutManager() + { + return new ViewportLayout(); + } + + /** + * Computes the parameters for the blitting scroll method. <code>dx</code> + * and <code>dy</code> specifiy the X and Y offset by which the viewport + * is scrolled. All other arguments are output parameters and are filled by + * this method. + * + * <code>blitFrom</code> holds the position of the blit rectangle in the + * viewport rectangle before scrolling, <code>blitTo</code> where the blitArea + * is copied to. + * + * <code>blitSize</code> holds the size of the blit area and + * <code>blitPaint</code> is the area of the view that needs to be painted. + * + * This method returns <code>true</code> if blitting is possible and + * <code>false</code> if the viewport has to be repainted completetly without + * blitting. + * + * @param dx the horizontal delta + * @param dy the vertical delta + * @param blitFrom the position from where to blit; set by this method + * @param blitTo the position where to blit area is copied to; set by this + * method + * @param blitSize the size of the blitted area; set by this method + * @param blitPaint the area that needs repainting; set by this method + * + * @return <code>true</code> if blitting is possible, + * <code>false</code> otherwise + */ + protected boolean computeBlit(int dx, int dy, Point blitFrom, Point blitTo, + Dimension blitSize, Rectangle blitPaint) + { + if ((dx != 0 && dy != 0) || (dy == 0 && dy == 0) || damaged) + // We cannot blit if the viewport is scrolled in both directions at + // once. Also, we do not want to blit if the viewport is not scrolled at + // all, because that probably means the view component repaints itself + // and the buffer needs updating. + return false; + + Rectangle portBounds = SwingUtilities.calculateInnerArea(this, getBounds()); + + // Compute the blitFrom and blitTo parameters. + blitFrom.x = portBounds.x; + blitFrom.y = portBounds.y; + blitTo.x = portBounds.x; + blitTo.y = portBounds.y; + + if (dy > 0) + { + blitFrom.y = portBounds.y + dy; + } + else if (dy < 0) + { + blitTo.y = portBounds.y - dy; + } + else if (dx > 0) + { + blitFrom.x = portBounds.x + dx; + } + else if (dx < 0) + { + blitTo.x = portBounds.x - dx; + } + + // Compute size of the blit area. + if (dx != 0) + { + blitSize.width = portBounds.width - Math.abs(dx); + blitSize.height = portBounds.height; + } + else if (dy != 0) + { + blitSize.width = portBounds.width; + blitSize.height = portBounds.height - Math.abs(dy); + } + + // Compute the blitPaint parameter. + blitPaint.setBounds(portBounds); + if (dy > 0) + { + blitPaint.y = portBounds.y + portBounds.height - dy; + blitPaint.height = dy; + } + else if (dy < 0) + { + blitPaint.height = -dy; + } + if (dx > 0) + { + blitPaint.x = portBounds.x + portBounds.width - dx; + blitPaint.width = dx; + } + else if (dx < 0) + { + blitPaint.width = -dx; + } + + return true; + } + + /** + * Paints the viewport in case we have a scrollmode of + * {@link #SIMPLE_SCROLL_MODE}. + * + * This simply paints the view directly on the surface of the viewport. + * + * @param g the graphics context to use + */ + void paintSimple(Graphics g) + { + // We need to call this to properly clear the background. + paintComponent(g); + + Point pos = getViewPosition(); + Component view = getView(); + Shape oldClip = g.getClip(); + g.clipRect(0, 0, getWidth(), getHeight()); + boolean translated = false; + try + { + g.translate(-pos.x, -pos.y); + translated = true; + view.paint(g); + } + finally + { + if (translated) + g.translate (pos.x, pos.y); + g.setClip(oldClip); + } + } + + /** + * Paints the viewport in case we have a scroll mode of + * {@link #BACKINGSTORE_SCROLL_MODE}. + * + * This method uses a backing store image to paint the view to, which is then + * subsequently painted on the screen. This should make scrolling more + * smooth. + * + * @param g the graphics context to use + */ + void paintBackingStore(Graphics g) + { + // If we have no backing store image yet or the size of the component has + // changed, we need to rebuild the backing store. + if (backingStoreImage == null || sizeChanged) + { + backingStoreImage = createImage(getWidth(), getHeight()); + sizeChanged = false; + Graphics g2 = backingStoreImage.getGraphics(); + paintSimple(g2); + g2.dispose(); + } + // Otherwise we can perform the blitting on the backing store image: + // First we move the part that remains visible after scrolling, then + // we only need to paint the bit that becomes newly visible. + else + { + Graphics g2 = backingStoreImage.getGraphics(); + Point viewPosition = getViewPosition(); + int dx = viewPosition.x - lastPaintPosition.x; + int dy = viewPosition.y - lastPaintPosition.y; + boolean canBlit = computeBlit(dx, dy, cachedBlitFrom, cachedBlitTo, + cachedBlitSize, cachedBlitPaint); + if (canBlit && isPaintRoot) + { + // Copy the part that remains visible during scrolling. + if (cachedBlitSize.width > 0 && cachedBlitSize.height > 0) + { + g2.copyArea(cachedBlitFrom.x, cachedBlitFrom.y, + cachedBlitSize.width, cachedBlitSize.height, + cachedBlitTo.x - cachedBlitFrom.x, + cachedBlitTo.y - cachedBlitFrom.y); + } + // Now paint the part that becomes newly visible. + g2.setClip(cachedBlitPaint.x, cachedBlitPaint.y, + cachedBlitPaint.width, cachedBlitPaint.height); + paintSimple(g2); + } + // If blitting is not possible for some reason, fall back to repainting + // everything. + else + { + // If the image has not been scrolled at all, only the changed + // clip must be updated in the buffer. + if (dx == 0 && dy == 0) + g2.setClip(g.getClip()); + + paintSimple(g2); + } + g2.dispose(); + } + // Actually draw the backingstore image to the graphics context. + g.drawImage(backingStoreImage, 0, 0, this); + // Update the lastPaintPosition so that we know what is already drawn when + // we paint the next time. + lastPaintPosition.setLocation(getViewPosition()); + } + + /** + * Paints the viewport in case we have a scrollmode of + * {@link #BLIT_SCROLL_MODE}. + * + * This paints the viewport using a backingstore and a blitting algorithm. + * Only the newly exposed area of the view is painted from the view painting + * methods, the remainder is copied from the backing store. + * + * @param g the graphics context to use + */ + void paintBlit(Graphics g) + { + // First we move the part that remains visible after scrolling, then + // we only need to paint the bit that becomes newly visible. + Point viewPosition = getViewPosition(); + int dx = viewPosition.x - lastPaintPosition.x; + int dy = viewPosition.y - lastPaintPosition.y; + boolean canBlit = computeBlit(dx, dy, cachedBlitFrom, cachedBlitTo, + cachedBlitSize, cachedBlitPaint); + if (canBlit && isPaintRoot) + { + // Copy the part that remains visible during scrolling. + if (cachedBlitSize.width > 0 && cachedBlitSize.width > 0) + { + g.copyArea(cachedBlitFrom.x, cachedBlitFrom.y, + cachedBlitSize.width, cachedBlitSize.height, + cachedBlitTo.x - cachedBlitFrom.x, + cachedBlitTo.y - cachedBlitFrom.y); + } + // Now paint the part that becomes newly visible. + Shape oldClip = g.getClip(); + g.clipRect(cachedBlitPaint.x, cachedBlitPaint.y, + cachedBlitPaint.width, cachedBlitPaint.height); + try + { + paintSimple(g); + } + finally + { + g.setClip(oldClip); + } + } + // If blitting is not possible for some reason, fall back to repainting + // everything. + else + paintSimple(g); + lastPaintPosition.setLocation(getViewPosition()); + } + + /** + * Overridden from JComponent to set the {@link #isPaintRoot} flag. + * + * @param x the rectangle to paint, X coordinate + * @param y the rectangle to paint, Y coordinate + * @param w the rectangle to paint, width + * @param h the rectangle to paint, height + */ + void paintImmediately2(int x, int y, int w, int h) + { + isPaintRoot = true; + super.paintImmediately2(x, y, w, h); + isPaintRoot = false; + } + + /** + * Returns true when the JViewport is using a backbuffer, so that we + * can update our backbuffer correctly. + */ + boolean isPaintRoot() + { + return scrollMode == BACKINGSTORE_SCROLL_MODE; + } +} |