alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2000 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.openide.util.datatransfer;

import java.awt.datatransfer.*;
import javax.swing.event.EventListenerList;

// and holding a list of services built over data flavors. [???]
/** Extended clipboard that supports listeners that can be notified about
* changes of content. Also contains support for attaching content convertors.
*
* @author Jaroslav Tulach
*/
public abstract class ExClipboard extends Clipboard {
    /** listeners */
    private EventListenerList listeners = new EventListenerList ();

    /** Make a new clipboard.
    * @param name name of the clipboard
    */
    public ExClipboard (String name) {
        super (name);
    }

    /** Add a listener to clipboard operations.
    * @param list the listener
    */
    public final void addClipboardListener (ClipboardListener list) {
        listeners.add (ClipboardListener.class, list);
    }

    /** Remove a listener to clipboard operations.
    * @param list the listener
    */
    public final void removeClipboardListener (ClipboardListener list) {
        listeners.remove (ClipboardListener.class, list);
    }

    /** Fires event about change of content in the clipboard.
    */
    protected final void fireClipboardChange () {
        Object[] l = listeners.getListenerList ();
        ClipboardEvent ev = null;
        for (int i = l.length - 2; i >= 0; i -= 2) {
            ClipboardListener list = (ClipboardListener)l[i + 1];
            if (ev == null) {
                ev = new ClipboardEvent (this);
            }
            list.clipboardChanged (ev);
        }
    }

    /** Obtain a list of convertors assigned to
    * this clipboard.
    * @return the convertors
    */
    protected abstract Convertor[] getConvertors ();


    /** Method that takes a transferable, applies all convertors,
    * and creates a new transferable using the abilities of the
    * convertors.
    * 

* This method is used when the contents of the clipboard are changed and * also can be used by Drag & Drop to process transferables between source * and target. *

* Note that it is possible for the results to vary according to order * of the convertors as specified by {@link #getConvertors}. For example, * the input transferable may contain flavor A, and there may be a convertor * from A to B, and one from B to C; flavor B will always be available, but * flavor C will only be available if the convertor list is in the order * that these were mentioned. Since the standard clipboard implementation * searches for convertors in lookup as well as manifests, ordering might be * specified between a set of layer-supplied convertors by means of folder * ordering attributes. * * @param t input transferable * @return new transferable */ public Transferable convert (Transferable t) { Convertor[] convertors = getConvertors (); for (int i = 0; i < convertors.length; i++) t = convertors[i].convert (t); return t; } /** Notifies the transferable that it has been accepted by a drop. * Works only for ExTransferable, other types of transferables are * not notified. * * @param t transferable to notify its listeners * @param action which action has been performed */ public static void transferableAccepted (Transferable t, int action) { if (t instanceof ExTransferable) { ((ExTransferable)t).fireAccepted (action); } else if (t.isDataFlavorSupported (ExTransferable.multiFlavor)) { try { MultiTransferObject mto = (MultiTransferObject)t.getTransferData (ExTransferable.multiFlavor); int cnt = mto.getCount (); for (int i = 0; i < cnt; i++) { transferableAccepted (mto.getTransferableAt (i), action); } } catch (Exception e) { // shouldn't occure } } } /** Notifies the transferable that it has been rejected by a drop. * Works only for ExTransferable, other types of transferables are * not notified. * * @param t transferable to notify its listeners */ public static void transferableRejected (Transferable t) { if (t instanceof ExTransferable) { ((ExTransferable)t).fireRejected (); } else if (t.isDataFlavorSupported (ExTransferable.multiFlavor)) { try { MultiTransferObject mto = (MultiTransferObject)t.getTransferData (ExTransferable.multiFlavor); int cnt = mto.getCount (); for (int i = 0; i < cnt; i++) { transferableRejected (mto.getTransferableAt (i)); } } catch (Exception e) { // shouldn't occure } } } public synchronized void setContents(Transferable contents, ClipboardOwner owner) { if (this.contents != null) transferableOwnershipLost(this.contents); super.setContents(contents, owner); } /** Notifies the transferable that it has lost ownership in clipboard. * Works only for ExTransferable, other types of transferables are * not notified. * * @param t transferable to notify its listeners */ public static void transferableOwnershipLost (Transferable t) { if (t instanceof ExTransferable) { ((ExTransferable)t).fireOwnershipLost (); } else if (t.isDataFlavorSupported (ExTransferable.multiFlavor)) { try { MultiTransferObject mto = (MultiTransferObject)t.getTransferData (ExTransferable.multiFlavor); int cnt = mto.getCount (); for (int i = 0; i < cnt; i++) { transferableOwnershipLost (mto.getTransferableAt (i)); } } catch (Exception e) { // shouldn't occure } } } /** Convertor that can convert the {@link Transferable contents} of a clipboard to * additional {@link DataFlavor flavors}. */ public interface Convertor { /** Convert a given transferable to a new transferable, * generally one which adds new flavors based on the existing flavors. * The recommended usage is as follows: * *

        * public Transferable convert (final Transferable t) {
        *   if (! t.isDataFlavorSupported (fromFlavor)) return t;
        *   if (t.isDataFlavorSupported (toFlavor)) return t;
        *   ExTransferable et = ExTransferable.create (t);
        *   et.put (new ExTransferable.Single (toFlavor) {
        *     public Object getData () throws IOException, UnsupportedFlavorException {
        *       FromObject from = (FromObject) t.getTransferData (fromFlavor);
        *       ToObject to = translateFormats (from);
        *       return to;
        *     }
        *   });
        *   return et;
        * }
        * 
* *
Note that this does not perform the conversion until toFlavor is * actually requested, nor does it advertise toFlavor as being available * unless fromFlavor already was. * *

You may also want to convert some flavor to a node selection, in which case you should do: * *

        * public Transferable convert (final Transferable t) {
        *   if (! t.isDataFlavorSupported (DataFlavor.stringFlavor)) return t;
        *   if (NodeTransfer.findPaste (t) != null) return t;
        *   ExTransferable et = ExTransferable.create (t);
        *   et.put (NodeTransfer.createPaste (new NodeTransfer.Paste () {
        *     public PasteType[] types (Node target) {
        *       if (isSuitable (target)) {
        *         return new PasteType[] { new PasteType () {
        *           public Transferable paste () throws IOException {
        *             try {
        *               String s = (String) t.getTransferData (DataFlavor.stringFlavor);
        *               addNewSubnode (target, s);
        *             } catch (UnsupportedFlavorException ufe) {
        *               throw new IOException (ufe.toString ());
        *             }
        *             return t;
        *           }
        *         }};
        *       } else {
        *         return new PasteType[0];
        *       }
        *     }
        *   }));
        *   return et;
        * }
        * 
* *

Convertors should generally avoid removing flavors from the transferable, * or changing the data for an existing flavor. * * @param t the incoming basic transferable * @return a possible enhanced transferable */ public Transferable convert (Transferable t); } }

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.