src/java.desktop/share/classes/javax/swing/JViewport.java

Print this page


   1 /*
   2  * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.swing;
  27 
  28 import java.awt.*;
  29 import java.awt.event.*;
  30 import java.awt.peer.ComponentPeer;
  31 import java.beans.Transient;
  32 import javax.swing.plaf.ViewportUI;
  33 
  34 import javax.swing.event.*;
  35 import javax.swing.border.*;
  36 import javax.accessibility.*;
  37 
  38 import java.io.Serializable;
  39 


  40 /**
  41  * The "viewport" or "porthole" through which you see the underlying
  42  * information. When you scroll, what moves is the viewport. It is like
  43  * peering through a camera's viewfinder. Moving the viewfinder upwards
  44  * brings new things into view at the top of the picture and loses
  45  * things that were at the bottom.
  46  * <p>
  47  * By default, <code>JViewport</code> is opaque. To change this, use the
  48  * <code>setOpaque</code> method.
  49  * <p>
  50  * <b>NOTE:</b>We have implemented a faster scrolling algorithm that
  51  * does not require a buffer to draw in. The algorithm works as follows:
  52  * <ol><li>The view and parent view and checked to see if they are
  53  * <code>JComponents</code>,
  54  * if they aren't, stop and repaint the whole viewport.
  55  * <li>If the viewport is obscured by an ancestor, stop and repaint the whole
  56  * viewport.
  57  * <li>Compute the region that will become visible, if it is as big as
  58  * the viewport, stop and repaint the whole view region.
  59  * <li>Obtain the ancestor <code>Window</code>'s graphics and


 363 
 364     /**
 365      * Scrolls the view so that <code>Rectangle</code>
 366      * within the view becomes visible.
 367      * <p>
 368      * This attempts to validate the view before scrolling if the
 369      * view is currently not valid - <code>isValid</code> returns false.
 370      * To avoid excessive validation when the containment hierarchy is
 371      * being created this will not validate if one of the ancestors does not
 372      * have a peer, or there is no validate root ancestor, or one of the
 373      * ancestors is not a <code>Window</code> or <code>Applet</code>.
 374      * <p>
 375      * Note that this method will not scroll outside of the
 376      * valid viewport; for example, if <code>contentRect</code> is larger
 377      * than the viewport, scrolling will be confined to the viewport's
 378      * bounds.
 379      *
 380      * @param contentRect the <code>Rectangle</code> to display
 381      * @see JComponent#isValidateRoot
 382      * @see java.awt.Component#isValid
 383      * @see java.awt.Component#getPeer
 384      */
 385     public void scrollRectToVisible(Rectangle contentRect) {
 386         Component view = getView();
 387 
 388         if (view == null) {
 389             return;
 390         } else {
 391             if (!view.isValid()) {
 392                 // If the view is not valid, validate. scrollRectToVisible
 393                 // may fail if the view is not valid first, contentRect
 394                 // could be bigger than invalid size.
 395                 validateView();
 396             }
 397             int dx, dy;
 398 
 399             dx = positionAdjustment(getWidth(), contentRect.width, contentRect.x);
 400             dy = positionAdjustment(getHeight(), contentRect.height, contentRect.y);
 401 
 402             if (dx != 0 || dy != 0) {
 403                 Point viewPosition = getViewPosition();


1431      * @param propertyName a string containing the property name
1432      * @param oldValue the old value of the property
1433      * @param newValue  the new value of the property
1434      */
1435     protected void firePropertyChange(String propertyName, Object oldValue,
1436                                       Object newValue) {
1437         super.firePropertyChange(propertyName, oldValue, newValue);
1438         if (propertyName.equals(EnableWindowBlit)) {
1439             if (newValue != null) {
1440                 setScrollMode(BLIT_SCROLL_MODE);
1441             } else {
1442                 setScrollMode(SIMPLE_SCROLL_MODE);
1443             }
1444         }
1445     }
1446 
1447     /**
1448      * Returns true if the component needs to be completely repainted after
1449      * a blit and a paint is received.
1450      */
1451     @SuppressWarnings("deprecation")
1452     private boolean needsRepaintAfterBlit() {
1453         // Find the first heavy weight ancestor. isObscured and
1454         // canDetermineObscurity are only appropriate for heavy weights.
1455         Component heavyParent = getParent();
1456 
1457         while (heavyParent != null && heavyParent.isLightweight()) {
1458             heavyParent = heavyParent.getParent();
1459         }
1460 
1461         if (heavyParent != null) {
1462             ComponentPeer peer = heavyParent.getPeer();

1463 
1464             if (peer != null && peer.canDetermineObscurity() &&
1465                                 !peer.isObscured()) {
1466                 // The peer says we aren't obscured, therefore we can assume
1467                 // that we won't later be messaged to paint a portion that
1468                 // we tried to blit that wasn't valid.
1469                 // It is certainly possible that when we blited we were
1470                 // obscured, and by the time this is invoked we aren't, but the
1471                 // chances of that happening are pretty slim.
1472                 return false;
1473             }
1474         }
1475         return true;
1476     }
1477 
1478     private Timer createRepaintTimer() {
1479         Timer timer = new Timer(300, new ActionListener() {
1480             public void actionPerformed(ActionEvent ae) {
1481                 // waitingForRepaint will be false if a paint came down
1482                 // with the complete clip rect, in which case we don't


   1 /*
   2  * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.swing;
  27 
  28 import java.awt.*;
  29 import java.awt.event.*;
  30 import java.awt.peer.ComponentPeer;
  31 import java.beans.Transient;
  32 import javax.swing.plaf.ViewportUI;
  33 
  34 import javax.swing.event.*;
  35 import javax.swing.border.*;
  36 import javax.accessibility.*;
  37 
  38 import java.io.Serializable;
  39 
  40 import sun.awt.AWTAccessor;
  41 
  42 /**
  43  * The "viewport" or "porthole" through which you see the underlying
  44  * information. When you scroll, what moves is the viewport. It is like
  45  * peering through a camera's viewfinder. Moving the viewfinder upwards
  46  * brings new things into view at the top of the picture and loses
  47  * things that were at the bottom.
  48  * <p>
  49  * By default, <code>JViewport</code> is opaque. To change this, use the
  50  * <code>setOpaque</code> method.
  51  * <p>
  52  * <b>NOTE:</b>We have implemented a faster scrolling algorithm that
  53  * does not require a buffer to draw in. The algorithm works as follows:
  54  * <ol><li>The view and parent view and checked to see if they are
  55  * <code>JComponents</code>,
  56  * if they aren't, stop and repaint the whole viewport.
  57  * <li>If the viewport is obscured by an ancestor, stop and repaint the whole
  58  * viewport.
  59  * <li>Compute the region that will become visible, if it is as big as
  60  * the viewport, stop and repaint the whole view region.
  61  * <li>Obtain the ancestor <code>Window</code>'s graphics and


 365 
 366     /**
 367      * Scrolls the view so that <code>Rectangle</code>
 368      * within the view becomes visible.
 369      * <p>
 370      * This attempts to validate the view before scrolling if the
 371      * view is currently not valid - <code>isValid</code> returns false.
 372      * To avoid excessive validation when the containment hierarchy is
 373      * being created this will not validate if one of the ancestors does not
 374      * have a peer, or there is no validate root ancestor, or one of the
 375      * ancestors is not a <code>Window</code> or <code>Applet</code>.
 376      * <p>
 377      * Note that this method will not scroll outside of the
 378      * valid viewport; for example, if <code>contentRect</code> is larger
 379      * than the viewport, scrolling will be confined to the viewport's
 380      * bounds.
 381      *
 382      * @param contentRect the <code>Rectangle</code> to display
 383      * @see JComponent#isValidateRoot
 384      * @see java.awt.Component#isValid

 385      */
 386     public void scrollRectToVisible(Rectangle contentRect) {
 387         Component view = getView();
 388 
 389         if (view == null) {
 390             return;
 391         } else {
 392             if (!view.isValid()) {
 393                 // If the view is not valid, validate. scrollRectToVisible
 394                 // may fail if the view is not valid first, contentRect
 395                 // could be bigger than invalid size.
 396                 validateView();
 397             }
 398             int dx, dy;
 399 
 400             dx = positionAdjustment(getWidth(), contentRect.width, contentRect.x);
 401             dy = positionAdjustment(getHeight(), contentRect.height, contentRect.y);
 402 
 403             if (dx != 0 || dy != 0) {
 404                 Point viewPosition = getViewPosition();


1432      * @param propertyName a string containing the property name
1433      * @param oldValue the old value of the property
1434      * @param newValue  the new value of the property
1435      */
1436     protected void firePropertyChange(String propertyName, Object oldValue,
1437                                       Object newValue) {
1438         super.firePropertyChange(propertyName, oldValue, newValue);
1439         if (propertyName.equals(EnableWindowBlit)) {
1440             if (newValue != null) {
1441                 setScrollMode(BLIT_SCROLL_MODE);
1442             } else {
1443                 setScrollMode(SIMPLE_SCROLL_MODE);
1444             }
1445         }
1446     }
1447 
1448     /**
1449      * Returns true if the component needs to be completely repainted after
1450      * a blit and a paint is received.
1451      */

1452     private boolean needsRepaintAfterBlit() {
1453         // Find the first heavy weight ancestor. isObscured and
1454         // canDetermineObscurity are only appropriate for heavy weights.
1455         Component heavyParent = getParent();
1456 
1457         while (heavyParent != null && heavyParent.isLightweight()) {
1458             heavyParent = heavyParent.getParent();
1459         }
1460 
1461         if (heavyParent != null) {
1462             ComponentPeer peer = AWTAccessor.getComponentAccessor()
1463                                             .getPeer(heavyParent);
1464 
1465             if (peer != null && peer.canDetermineObscurity() &&
1466                                 !peer.isObscured()) {
1467                 // The peer says we aren't obscured, therefore we can assume
1468                 // that we won't later be messaged to paint a portion that
1469                 // we tried to blit that wasn't valid.
1470                 // It is certainly possible that when we blited we were
1471                 // obscured, and by the time this is invoked we aren't, but the
1472                 // chances of that happening are pretty slim.
1473                 return false;
1474             }
1475         }
1476         return true;
1477     }
1478 
1479     private Timer createRepaintTimer() {
1480         Timer timer = new Timer(300, new ActionListener() {
1481             public void actionPerformed(ActionEvent ae) {
1482                 // waitingForRepaint will be false if a paint came down
1483                 // with the complete clip rect, in which case we don't