src/share/classes/sun/swing/JLightweightFrame.java

Print this page




  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 sun.swing;
  27 
  28 import java.awt.BorderLayout;
  29 import java.awt.Color;
  30 import java.awt.Component;
  31 import java.awt.Container;

  32 import java.awt.EventQueue;
  33 import java.awt.Graphics;
  34 import java.awt.Graphics2D;
  35 import java.awt.Rectangle;



  36 import java.awt.image.BufferedImage;
  37 import java.awt.image.DataBufferInt;


  38 import java.security.AccessController;
  39 
  40 import javax.swing.JLayeredPane;
  41 import javax.swing.JPanel;
  42 import javax.swing.JRootPane;
  43 import javax.swing.LayoutFocusTraversalPolicy;
  44 import javax.swing.RootPaneContainer;
  45 
  46 import sun.awt.LightweightFrame;
  47 import sun.security.action.GetPropertyAction;
  48 
  49 /**
  50  * The frame serves as a lightweight container which paints its content
  51  * to an offscreen image and provides access to the image's data via the
  52  * {@link LightweightContent} interface. Note, that it may not be shown
  53  * as a standalone toplevel frame. Its purpose is to provide functionality
  54  * for lightweight embedding.
  55  *
  56  * @author Artem Ananiev
  57  * @author Anton Tarasov


  63     private LightweightContent content;
  64 
  65     private Component component;
  66     private JPanel contentPane;
  67 
  68     private BufferedImage bbImage;
  69 
  70     /**
  71      * {@code copyBufferEnabled}, true by default, defines the following strategy.
  72      * A duplicating (copy) buffer is created for the original pixel buffer.
  73      * The copy buffer is synchronized with the original buffer every time the
  74      * latter changes. {@code JLightweightFrame} passes the copy buffer array
  75      * to the {@link LightweightContent#imageBufferReset} method. The code spot
  76      * which synchronizes two buffers becomes the only critical section guarded
  77      * by the lock (managed with the {@link LightweightContent#paintLock()},
  78      * {@link LightweightContent#paintUnlock()} methods).
  79      */
  80     private boolean copyBufferEnabled;
  81     private int[] copyBuffer;
  82 


  83     /**
  84      * Constructs a new, initially invisible {@code JLightweightFrame}
  85      * instance.
  86      */
  87     public JLightweightFrame() {
  88         super();
  89         copyBufferEnabled = "true".equals(AccessController.
  90             doPrivileged(new GetPropertyAction("jlf.copyBufferEnabled", "true")));
  91 
  92         add(rootPane, BorderLayout.CENTER);
  93         setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
  94         if (getGraphicsConfiguration().isTranslucencyCapable()) {
  95             setBackground(new Color(0, 0, 0, 0));
  96         }

















  97     }
  98 
  99     /**
 100      * Sets the {@link LightweightContent} instance for this frame.
 101      * The {@code JComponent} object returned by the
 102      * {@link LightweightContent#getComponent()} method is immediately
 103      * added to the frame's content pane.
 104      *
 105      * @param content the {@link LightweightContent} instance
 106      */
 107     public void setContent(LightweightContent content) {




 108         this.content = content;
 109         this.component = content.getComponent();
 110 









 111         initInterior();
 112     }
 113 
 114     @Override
 115     public Graphics getGraphics() {
 116         if (bbImage == null) return null;
 117 
 118         Graphics2D g = bbImage.createGraphics();
 119         g.setBackground(getBackground());
 120         g.setColor(getForeground());
 121         g.setFont(getFont());
 122         return g;
 123     }
 124 
 125     /**
 126      * {@inheritDoc}
 127      *
 128      * @see LightweightContent#focusGrabbed()
 129      */
 130     @Override


 185                             if (copyBufferEnabled) {
 186                                 syncCopyBuffer(false, clip.x, clip.y, clip.width, clip.height);
 187                             }
 188                             content.imageUpdated(clip.x, clip.y, clip.width, clip.height);
 189                         }
 190                     });
 191                 } finally {
 192                     if (!copyBufferEnabled) {
 193                         content.paintUnlock();
 194                     }
 195                 }
 196             }
 197             @Override
 198             protected boolean isPaintingOrigin() {
 199                 return true;
 200             }
 201         };
 202         contentPane.setLayout(new BorderLayout());
 203         contentPane.add(component);
 204         setContentPane(contentPane);



















 205     }
 206 
 207     @SuppressWarnings("deprecation")
 208     @Override public void reshape(int x, int y, int width, int height) {
 209         super.reshape(x, y, width, height);
 210 
 211         if (width == 0 || height == 0) {
 212             return;
 213         }
 214         if (!copyBufferEnabled) {
 215             content.paintLock();
 216         }
 217         try {
 218             if ((bbImage == null) || (width != bbImage.getWidth()) || (height != bbImage.getHeight())) {
 219                 boolean createBB = true;
 220                 int newW = width;
 221                 int newH = height;
 222                 if (bbImage != null) {
 223                     int oldW = bbImage.getWidth();
 224                     int oldH = bbImage.getHeight();




  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 sun.swing;
  27 
  28 import java.awt.BorderLayout;
  29 import java.awt.Color;
  30 import java.awt.Component;
  31 import java.awt.Container;
  32 import java.awt.Dimension;
  33 import java.awt.EventQueue;
  34 import java.awt.Graphics;
  35 import java.awt.Graphics2D;
  36 import java.awt.Rectangle;
  37 import java.awt.event.ComponentListener;
  38 import java.awt.event.ContainerEvent;
  39 import java.awt.event.ContainerListener;
  40 import java.awt.image.BufferedImage;
  41 import java.awt.image.DataBufferInt;
  42 import java.beans.PropertyChangeEvent;
  43 import java.beans.PropertyChangeListener;
  44 import java.security.AccessController;
  45 
  46 import javax.swing.JLayeredPane;
  47 import javax.swing.JPanel;
  48 import javax.swing.JRootPane;
  49 import javax.swing.LayoutFocusTraversalPolicy;
  50 import javax.swing.RootPaneContainer;
  51 
  52 import sun.awt.LightweightFrame;
  53 import sun.security.action.GetPropertyAction;
  54 
  55 /**
  56  * The frame serves as a lightweight container which paints its content
  57  * to an offscreen image and provides access to the image's data via the
  58  * {@link LightweightContent} interface. Note, that it may not be shown
  59  * as a standalone toplevel frame. Its purpose is to provide functionality
  60  * for lightweight embedding.
  61  *
  62  * @author Artem Ananiev
  63  * @author Anton Tarasov


  69     private LightweightContent content;
  70 
  71     private Component component;
  72     private JPanel contentPane;
  73 
  74     private BufferedImage bbImage;
  75 
  76     /**
  77      * {@code copyBufferEnabled}, true by default, defines the following strategy.
  78      * A duplicating (copy) buffer is created for the original pixel buffer.
  79      * The copy buffer is synchronized with the original buffer every time the
  80      * latter changes. {@code JLightweightFrame} passes the copy buffer array
  81      * to the {@link LightweightContent#imageBufferReset} method. The code spot
  82      * which synchronizes two buffers becomes the only critical section guarded
  83      * by the lock (managed with the {@link LightweightContent#paintLock()},
  84      * {@link LightweightContent#paintUnlock()} methods).
  85      */
  86     private boolean copyBufferEnabled;
  87     private int[] copyBuffer;
  88     
  89     private PropertyChangeListener layoutSizeListener;
  90 
  91     /**
  92      * Constructs a new, initially invisible {@code JLightweightFrame}
  93      * instance.
  94      */
  95     public JLightweightFrame() {
  96         super();
  97         copyBufferEnabled = "true".equals(AccessController.
  98             doPrivileged(new GetPropertyAction("jlf.copyBufferEnabled", "true")));
  99 
 100         add(rootPane, BorderLayout.CENTER);
 101         setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
 102         if (getGraphicsConfiguration().isTranslucencyCapable()) {
 103             setBackground(new Color(0, 0, 0, 0));
 104         }
 105         
 106         layoutSizeListener = new PropertyChangeListener() {
 107             @Override
 108             public void propertyChange(PropertyChangeEvent e) {
 109                 Dimension d = (Dimension)e.getNewValue();
 110                 
 111                 if ("preferredSize".equals(e.getPropertyName())) {
 112                     content.preferredSizeChanged(d.width, d.height);
 113                     
 114                 } else if ("maximumSize".equals(e.getPropertyName())) {
 115                     content.maximumSizeChanged(d.width, d.height);
 116                     
 117                 } else if ("minimumSize".equals(e.getPropertyName())) {
 118                     content.minimumSizeChanged(d.width, d.height);
 119                 }
 120             }
 121         };        
 122     }
 123 
 124     /**
 125      * Sets the {@link LightweightContent} instance for this frame.
 126      * The {@code JComponent} object returned by the
 127      * {@link LightweightContent#getComponent()} method is immediately
 128      * added to the frame's content pane.
 129      *
 130      * @param content the {@link LightweightContent} instance
 131      */
 132     public void setContent(final LightweightContent content) {
 133         if (content == null) {
 134             System.err.println("JLightweightFrame.setContent: content may not be null!");
 135             return;
 136         }
 137         this.content = content;
 138         this.component = content.getComponent();
 139 
 140         Dimension d = this.component.getPreferredSize();
 141         content.preferredSizeChanged(d.width, d.height);
 142         
 143         d = this.component.getMaximumSize();
 144         content.maximumSizeChanged(d.width, d.height);
 145         
 146         d = this.component.getMinimumSize();
 147         content.minimumSizeChanged(d.width, d.height);
 148         
 149         initInterior();
 150     }
 151 
 152     @Override
 153     public Graphics getGraphics() {
 154         if (bbImage == null) return null;
 155 
 156         Graphics2D g = bbImage.createGraphics();
 157         g.setBackground(getBackground());
 158         g.setColor(getForeground());
 159         g.setFont(getFont());
 160         return g;
 161     }
 162 
 163     /**
 164      * {@inheritDoc}
 165      *
 166      * @see LightweightContent#focusGrabbed()
 167      */
 168     @Override


 223                             if (copyBufferEnabled) {
 224                                 syncCopyBuffer(false, clip.x, clip.y, clip.width, clip.height);
 225                             }
 226                             content.imageUpdated(clip.x, clip.y, clip.width, clip.height);
 227                         }
 228                     });
 229                 } finally {
 230                     if (!copyBufferEnabled) {
 231                         content.paintUnlock();
 232                     }
 233                 }
 234             }
 235             @Override
 236             protected boolean isPaintingOrigin() {
 237                 return true;
 238             }
 239         };
 240         contentPane.setLayout(new BorderLayout());
 241         contentPane.add(component);
 242         setContentPane(contentPane);
 243         
 244         contentPane.addContainerListener(new ContainerListener() {
 245             @Override
 246             public void componentAdded(ContainerEvent e) {
 247                 Component c = JLightweightFrame.this.component;
 248                 if (e.getChild() == c) {
 249                     c.addPropertyChangeListener("preferredSize", layoutSizeListener);
 250                     c.addPropertyChangeListener("maximumSize", layoutSizeListener);
 251                     c.addPropertyChangeListener("minimumSize", layoutSizeListener);                    
 252                 }                
 253             }
 254             @Override
 255             public void componentRemoved(ContainerEvent e) {
 256                 Component c = JLightweightFrame.this.component;
 257                 if (e.getChild() == c) {
 258                     c.removePropertyChangeListener(layoutSizeListener);
 259                 }
 260             }
 261         });
 262     }
 263 
 264     @SuppressWarnings("deprecation")
 265     @Override public void reshape(int x, int y, int width, int height) {
 266         super.reshape(x, y, width, height);
 267 
 268         if (width == 0 || height == 0) {
 269             return;
 270         }
 271         if (!copyBufferEnabled) {
 272             content.paintLock();
 273         }
 274         try {
 275             if ((bbImage == null) || (width != bbImage.getWidth()) || (height != bbImage.getHeight())) {
 276                 boolean createBB = true;
 277                 int newW = width;
 278                 int newH = height;
 279                 if (bbImage != null) {
 280                     int oldW = bbImage.getWidth();
 281                     int oldH = bbImage.getHeight();