src/share/classes/sun/awt/datatransfer/desktop/SunClipboard.java

Print this page




   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 sun.awt.datatransfer;
  27 
  28 import java.awt.EventQueue;
  29 
  30 import java.awt.datatransfer.Clipboard;
  31 import java.awt.datatransfer.FlavorTable;
  32 import java.awt.datatransfer.SystemFlavorMap;
  33 import java.awt.datatransfer.Transferable;
  34 import java.awt.datatransfer.ClipboardOwner;
  35 import java.awt.datatransfer.DataFlavor;
  36 import java.awt.datatransfer.FlavorListener;
  37 import java.awt.datatransfer.FlavorEvent;
  38 import java.awt.datatransfer.UnsupportedFlavorException;
  39 
  40 import java.beans.PropertyChangeEvent;
  41 import java.beans.PropertyChangeListener;
  42 
  43 import java.util.Objects;
  44 import java.util.Set;
  45 import java.util.HashSet;
  46 
  47 import java.io.IOException;
  48 
  49 import sun.awt.AppContext;
  50 import sun.awt.PeerEvent;
  51 import sun.awt.SunToolkit;

  52 
  53 
  54 /**
  55  * Serves as a common, helper superclass for the Win32 and X11 system
  56  * Clipboards.
  57  *
  58  * @author Danila Sinopalnikov
  59  * @author Alexander Gerasimov
  60  *
  61  * @since 1.3
  62  */
  63 public abstract class SunClipboard extends Clipboard
  64     implements PropertyChangeListener {
  65 
  66     private AppContext contentsContext = null;
  67 
  68     private final Object CLIPBOARD_FLAVOR_LISTENER_KEY;
  69 
  70     /**
  71      * A number of <code>FlavorListener</code>s currently registered


 135     public synchronized Transferable getContents(Object requestor) {
 136         if (contents != null) {
 137             return contents;
 138         }
 139         return new ClipboardTransferable(this);
 140     }
 141 
 142 
 143     /**
 144      * @return the contents of this clipboard if it has been set from the same
 145      *         AppContext as it is currently retrieved or null otherwise
 146      * @since 1.5
 147      */
 148     private synchronized Transferable getContextContents() {
 149         AppContext context = AppContext.getAppContext();
 150         return (context == contentsContext) ? contents : null;
 151     }
 152 
 153 
 154     /**
 155      * @see java.awt.Clipboard#getAvailableDataFlavors
 156      * @since 1.5
 157      */
 158     public DataFlavor[] getAvailableDataFlavors() {
 159         Transferable cntnts = getContextContents();
 160         if (cntnts != null) {
 161             return cntnts.getTransferDataFlavors();
 162         }
 163 
 164         long[] formats = getClipboardFormatsOpenClose();
 165 
 166         return DataTransferer.getInstance().
 167             getFlavorsForFormatsAsArray(formats, getDefaultFlavorTable());
 168     }
 169 
 170     /**
 171      * @see java.awt.Clipboard#isDataFlavorAvailable
 172      * @since 1.5
 173      */
 174     public boolean isDataFlavorAvailable(DataFlavor flavor) {
 175         if (flavor == null) {
 176             throw new NullPointerException("flavor");
 177         }
 178 
 179         Transferable cntnts = getContextContents();
 180         if (cntnts != null) {
 181             return cntnts.isDataFlavorSupported(flavor);
 182         }
 183 
 184         long[] formats = getClipboardFormatsOpenClose();
 185 
 186         return formatArrayAsDataFlavorSet(formats).contains(flavor);
 187     }
 188 
 189     /**
 190      * @see java.awt.Clipboard#getData
 191      * @since 1.5
 192      */
 193     public Object getData(DataFlavor flavor)
 194         throws UnsupportedFlavorException, IOException {
 195         if (flavor == null) {
 196             throw new NullPointerException("flavor");
 197         }
 198 
 199         Transferable cntnts = getContextContents();
 200         if (cntnts != null) {
 201             return cntnts.getTransferData(flavor);
 202         }
 203 
 204         long format = 0;
 205         byte[] data = null;
 206         Transferable localeTransferable = null;
 207 
 208         try {
 209             openClipboard(null);
 210 


 400 
 401     public boolean areFlavorListenersRegistered() {
 402         return (numberOfFlavorListeners > 0);
 403     }
 404 
 405     protected abstract void registerClipboardViewerChecked();
 406 
 407     protected abstract void unregisterClipboardViewerChecked();
 408 
 409     /**
 410      * Checks change of the <code>DataFlavor</code>s and, if necessary,
 411      * posts notifications on <code>FlavorEvent</code>s to the
 412      * AppContexts' EDTs.
 413      * The parameter <code>formats</code> is null iff we have just
 414      * failed to get formats available on the clipboard.
 415      *
 416      * @param formats data formats that have just been retrieved from
 417      *        this clipboard
 418      */
 419     public void checkChange(long[] formats) {
 420         Set<DataFlavor> prevDataFlavors = currentDataFlavors;
 421         currentDataFlavors = formatArrayAsDataFlavorSet(formats);
 422 
 423         if (Objects.equals(prevDataFlavors, currentDataFlavors)) {
 424             // we've been able to successfully get available on the clipboard
 425             // DataFlavors this and previous time and they are coincident;
 426             // don't notify
 427             return;
 428         }
 429 
 430         for (AppContext appContext : AppContext.getAppContexts()) {
 431             if (appContext == null || appContext.isDisposed()) {
 432                 continue;
 433             }
 434             Set<FlavorListener> flavorListeners = getFlavorListeners(appContext);
 435             if (flavorListeners != null) {
 436                 for (FlavorListener listener : flavorListeners) {
 437                     if (listener != null) {
 438                         PeerEvent peerEvent = new PeerEvent(this,
 439                                 () -> listener.flavorsChanged(new FlavorEvent(SunClipboard.this)),
 440                                 PeerEvent.PRIORITY_EVENT);


   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 sun.awt.datatransfer.desktop;
  27 
  28 import java.awt.EventQueue;
  29 
  30 import java.awt.datatransfer.Clipboard;
  31 import java.awt.datatransfer.FlavorTable;
  32 import java.awt.datatransfer.SystemFlavorMap;
  33 import java.awt.datatransfer.Transferable;
  34 import java.awt.datatransfer.ClipboardOwner;
  35 import java.awt.datatransfer.DataFlavor;
  36 import java.awt.datatransfer.FlavorListener;
  37 import java.awt.datatransfer.FlavorEvent;
  38 import java.awt.datatransfer.UnsupportedFlavorException;
  39 
  40 import java.beans.PropertyChangeEvent;
  41 import java.beans.PropertyChangeListener;
  42 
  43 import java.util.Objects;
  44 import java.util.Set;
  45 import java.util.HashSet;
  46 
  47 import java.io.IOException;
  48 
  49 import sun.awt.AppContext;
  50 import sun.awt.PeerEvent;
  51 import sun.awt.SunToolkit;
  52 import sun.awt.datatransfer.TransferableProxy;
  53 
  54 
  55 /**
  56  * Serves as a common, helper superclass for the Win32 and X11 system
  57  * Clipboards.
  58  *
  59  * @author Danila Sinopalnikov
  60  * @author Alexander Gerasimov
  61  *
  62  * @since 1.3
  63  */
  64 public abstract class SunClipboard extends Clipboard
  65     implements PropertyChangeListener {
  66 
  67     private AppContext contentsContext = null;
  68 
  69     private final Object CLIPBOARD_FLAVOR_LISTENER_KEY;
  70 
  71     /**
  72      * A number of <code>FlavorListener</code>s currently registered


 136     public synchronized Transferable getContents(Object requestor) {
 137         if (contents != null) {
 138             return contents;
 139         }
 140         return new ClipboardTransferable(this);
 141     }
 142 
 143 
 144     /**
 145      * @return the contents of this clipboard if it has been set from the same
 146      *         AppContext as it is currently retrieved or null otherwise
 147      * @since 1.5
 148      */
 149     private synchronized Transferable getContextContents() {
 150         AppContext context = AppContext.getAppContext();
 151         return (context == contentsContext) ? contents : null;
 152     }
 153 
 154 
 155     /**
 156      * @see java.awt.datatransfer.Clipboard#getAvailableDataFlavors
 157      * @since 1.5
 158      */
 159     public DataFlavor[] getAvailableDataFlavors() {
 160         Transferable cntnts = getContextContents();
 161         if (cntnts != null) {
 162             return cntnts.getTransferDataFlavors();
 163         }
 164 
 165         long[] formats = getClipboardFormatsOpenClose();
 166 
 167         return DataTransferer.getInstance().
 168             getFlavorsForFormatsAsArray(formats, getDefaultFlavorTable());
 169     }
 170 
 171     /**
 172      * @see java.awt.datatransfer.Clipboard#isDataFlavorAvailable
 173      * @since 1.5
 174      */
 175     public boolean isDataFlavorAvailable(DataFlavor flavor) {
 176         if (flavor == null) {
 177             throw new NullPointerException("flavor");
 178         }
 179 
 180         Transferable cntnts = getContextContents();
 181         if (cntnts != null) {
 182             return cntnts.isDataFlavorSupported(flavor);
 183         }
 184 
 185         long[] formats = getClipboardFormatsOpenClose();
 186 
 187         return formatArrayAsDataFlavorSet(formats).contains(flavor);
 188     }
 189 
 190     /**
 191      * @see java.awt.datatransfer.Clipboard#getData
 192      * @since 1.5
 193      */
 194     public Object getData(DataFlavor flavor)
 195         throws UnsupportedFlavorException, IOException {
 196         if (flavor == null) {
 197             throw new NullPointerException("flavor");
 198         }
 199 
 200         Transferable cntnts = getContextContents();
 201         if (cntnts != null) {
 202             return cntnts.getTransferData(flavor);
 203         }
 204 
 205         long format = 0;
 206         byte[] data = null;
 207         Transferable localeTransferable = null;
 208 
 209         try {
 210             openClipboard(null);
 211 


 401 
 402     public boolean areFlavorListenersRegistered() {
 403         return (numberOfFlavorListeners > 0);
 404     }
 405 
 406     protected abstract void registerClipboardViewerChecked();
 407 
 408     protected abstract void unregisterClipboardViewerChecked();
 409 
 410     /**
 411      * Checks change of the <code>DataFlavor</code>s and, if necessary,
 412      * posts notifications on <code>FlavorEvent</code>s to the
 413      * AppContexts' EDTs.
 414      * The parameter <code>formats</code> is null iff we have just
 415      * failed to get formats available on the clipboard.
 416      *
 417      * @param formats data formats that have just been retrieved from
 418      *        this clipboard
 419      */
 420     public void checkChange(long[] formats) {
 421         Set prevDataFlavors = currentDataFlavors;
 422         currentDataFlavors = formatArrayAsDataFlavorSet(formats);
 423 
 424         if (Objects.equals(prevDataFlavors, currentDataFlavors)) {
 425             // we've been able to successfully get available on the clipboard
 426             // DataFlavors this and previous time and they are coincident;
 427             // don't notify
 428             return;
 429         }
 430 
 431         for (AppContext appContext : AppContext.getAppContexts()) {
 432             if (appContext == null || appContext.isDisposed()) {
 433                 continue;
 434             }
 435             Set<FlavorListener> flavorListeners = getFlavorListeners(appContext);
 436             if (flavorListeners != null) {
 437                 for (FlavorListener listener : flavorListeners) {
 438                     if (listener != null) {
 439                         PeerEvent peerEvent = new PeerEvent(this,
 440                                 () -> listener.flavorsChanged(new FlavorEvent(SunClipboard.this)),
 441                                 PeerEvent.PRIORITY_EVENT);