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

Print this page




  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.


 722                 clipB.height >= getHeight()) {
 723                 waitingForRepaint = false;
 724                 repaintTimer.stop();
 725             }
 726         }
 727 
 728         if (!backingStore || isBlitting() || getView() == null) {
 729             super.paint(g);
 730             lastPaintPosition = getViewLocation();
 731             return;
 732         }
 733 
 734         // If the view is smaller than the viewport and we are not opaque
 735         // (that is, we won't paint our background), we should set the
 736         // clip. Otherwise, as the bounds of the view vary, we will
 737         // blit garbage into the exposed areas.
 738         Rectangle viewBounds = getView().getBounds();
 739         if (!isOpaque()) {
 740             g.clipRect(0, 0, viewBounds.width, viewBounds.height);
 741         }


 742 
 743         if (backingStoreImage == null) {


 744             // Backing store is enabled but this is the first call to paint.
 745             // Create the backing store, paint it and then copy to g.
 746             // The backing store image will be created with the size of
 747             // the viewport. We must make sure the clip region is the
 748             // same size, otherwise when scrolling the backing image
 749             // the region outside of the clipped region will not be painted,
 750             // and result in empty areas.





 751             backingStoreImage = createImage(width, height);

 752             Rectangle clip = g.getClipBounds();
 753             if (clip.width != width || clip.height != height) {
 754                 if (!isOpaque()) {
 755                     g.setClip(0, 0, Math.min(viewBounds.width, width),
 756                               Math.min(viewBounds.height, height));
 757                 }
 758                 else {
 759                     g.setClip(0, 0, width, height);
 760                 }
 761                 paintViaBackingStore(g, clip);
 762             }
 763             else {
 764                 paintViaBackingStore(g);
 765             }
 766         }
 767         else {
 768             if (!scrollUnderway || lastPaintPosition.equals(getViewLocation())) {
 769                 // No scrolling happened: repaint required area via backing store.
 770                 paintViaBackingStore(g);
 771             } else {




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


 726                 clipB.height >= getHeight()) {
 727                 waitingForRepaint = false;
 728                 repaintTimer.stop();
 729             }
 730         }
 731 
 732         if (!backingStore || isBlitting() || getView() == null) {
 733             super.paint(g);
 734             lastPaintPosition = getViewLocation();
 735             return;
 736         }
 737 
 738         // If the view is smaller than the viewport and we are not opaque
 739         // (that is, we won't paint our background), we should set the
 740         // clip. Otherwise, as the bounds of the view vary, we will
 741         // blit garbage into the exposed areas.
 742         Rectangle viewBounds = getView().getBounds();
 743         if (!isOpaque()) {
 744             g.clipRect(0, 0, viewBounds.width, viewBounds.height);
 745         }
 746         int scale = g instanceof SunGraphics2D ?
 747                     ((SunGraphics2D)g).surfaceData.getDefaultScale() : 1;        
 748 
 749         if (backingStoreImage == null ||
 750             SurfaceManager.getImageScale(backingStoreImage) != scale)
 751         {
 752             // Backing store is enabled but this is the first call to paint.
 753             // Create the backing store, paint it and then copy to g.
 754             // The backing store image will be created with the size of
 755             // the viewport. We must make sure the clip region is the
 756             // same size, otherwise when scrolling the backing image
 757             // the region outside of the clipped region will not be painted,
 758             // and result in empty areas.
 759             Window w = SwingUtilities.getWindowAncestor(this);            
 760             if (w instanceof JLightweightFrame) {
 761                 backingStoreImage = ((JLightweightFrame)w).createHiDPIImage(width, height);
 762                 ((OffScreenImage)backingStoreImage).setReturnLayoutSize(true);
 763             } else {            
 764                 backingStoreImage = createImage(width, height);
 765             }
 766             Rectangle clip = g.getClipBounds();
 767             if (clip.width != width || clip.height != height) {
 768                 if (!isOpaque()) {
 769                     g.setClip(0, 0, Math.min(viewBounds.width, width),
 770                               Math.min(viewBounds.height, height));
 771                 }
 772                 else {
 773                     g.setClip(0, 0, width, height);
 774                 }
 775                 paintViaBackingStore(g, clip);
 776             }
 777             else {
 778                 paintViaBackingStore(g);
 779             }
 780         }
 781         else {
 782             if (!scrollUnderway || lastPaintPosition.equals(getViewLocation())) {
 783                 // No scrolling happened: repaint required area via backing store.
 784                 paintViaBackingStore(g);
 785             } else {