Spec-Zone .ru
спецификации, руководства, описания, API
001/*
002 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.  Oracle designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Oracle in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
022 * or visit www.oracle.com if you need additional information or have any
023 * questions.
024 */
025
026package javafx.scene.input;
027
028import java.util.Arrays;
029import java.util.Collections;
030import java.util.HashSet;
031import java.util.Iterator;
032import java.util.Set;
033
034import com.sun.javafx.WeakReferenceQueue;
035
036/**
037 * Data format identifier used as means
038 * of identifying the data stored on a clipboard/dragboard.
039 */
040public class DataFormat {
041
042    /**
043     * A static cache of all DataFormats created and currently in use. This is needed
044     * by the underlying implementation, such that, given a mime type, we can determine
045     * the associated DataFormat. The OS level is going to supply us with a mime type
046     * (or other string based key), and we need to be able to map this back to the FX
047     * DataFormat.
048     */
049    private static final WeakReferenceQueue<DataFormat> DATA_FORMAT_LIST = new WeakReferenceQueue<DataFormat>();
050
051    /**
052     * Represents a plain text string.
053     */
054    public static final DataFormat PLAIN_TEXT = new DataFormat("text/plain");
055
056    /**
057     * Represents an HTML formatted string.
058     */
059    public static final DataFormat HTML = new DataFormat("text/html");
060
061    /**
062     * Represents an RTF formatted string
063     */
064    public static final DataFormat RTF = new DataFormat("text/rtf");
065
066    /**
067     * Represents a URL, encoded as a String
068     */
069    public static final DataFormat URL = new DataFormat("text/uri-list");
070
071    /**
072     * A special platform specific image type, such as is commonly used
073     * on the clipboard and interoperates widely with other applications.
074     * For example, on Mac this might ultimately be a TIFF while on
075     * Windows it might be a DIB (device independent bitmap).
076     */
077    public static final DataFormat IMAGE = new DataFormat("application/x-java-rawimage");
078
079    /**
080     * Represents a List of Files.
081     */
082    public static final DataFormat FILES = new DataFormat("application/x-java-file-list", "java.file-list");
083
084    /**
085     * Data format used internally, represents dragged image. Making this
086     * a private field prevents user from creating this DataFormat and breaking
087     * our drag view implementation.
088     */
089    private static final DataFormat DRAG_IMAGE = new DataFormat("application/x-java-drag-image");
090
091    /**
092     * Data format used internally, represents offset in the dragged image.
093     * Making this a private field prevents user from creating this DataFormat
094     * and breaking our drag view implementation.
095     */
096    private static final DataFormat DRAG_IMAGE_OFFSET = new DataFormat("application/x-java-drag-image-offset");
097    
098    /**
099     * A set of identifiers, typically mime types, for this DataFormat. 
100     * In most cases this will be a single String.
101     */
102    private final Set<String> identifier;
103
104    /**
105     * Create a new DataFormat, specifying the set of ids that are associated with
106     * this data format. Typically the ids are one or more mime types. For each 
107     * id, any data associated with this DataFormat will be registered on the 
108     * clipboard. For example, suppose I had the following:
109     * <pre><code>
110     *     DataFormat fmt = new DataFormat("text/foo", "text/bar");
111     *     Clipboard clipboard = Clipboard.getSystemClipboard();
112     *     ClipboardContent content = new ClipboardContent();
113     *     content.pu(fmt, "Hello");
114     *     clipboard.setContent(content);
115     * </code></pre>
116     *
117     * With the above code, if I were to look on the clipboard, I'd find the String "Hello"
118     * listed both for "text/foo" and "text/bar" on the clipboard.
119     * @param ids The set of ids used to represent this DataFormat on the clipboard.
120     * @throws IllegalArgumentException if one of the given mime types is already
121     *         assigned to another DataFormat.
122     */
123    public DataFormat(String... ids) {
124        DATA_FORMAT_LIST.cleanup();
125        if (ids != null) {
126            for (String id : ids) {
127                if (lookupMimeType(id) != null) {
128                    throw new IllegalArgumentException("DataFormat '" + id +
129                            "' already exists.");
130                }
131            }
132            this.identifier = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(ids)));
133        } else {
134            this.identifier = Collections.<String>emptySet();
135        }
136
137        // Add to the statis data format list.
138        DATA_FORMAT_LIST.add(this);
139    }
140
141    /**
142     * Gets the unmodifiable set of identifiers for this DataFormat.
143     * @return an unmodifiable set that is never null.
144     */
145    public final Set<String> getIdentifiers() {
146        return identifier;
147    }
148    
149    /**
150     * Returns a string representation of this {@code DataFormat} object.
151     * @return a string representation of this {@code DataFormat} object.
152     */ 
153    @Override public String toString() {
154        if (identifier.isEmpty()) {
155            return "[]";
156        } else if (identifier.size() == 1) {
157            StringBuilder sb = new StringBuilder("[");
158            sb.append(identifier.iterator().next());
159            return (sb.append("]").toString());
160        } else {
161            StringBuilder b = new StringBuilder("[");
162            Iterator<String> itr = identifier.iterator();
163            while (itr.hasNext()) {
164                b = b.append(itr.next());
165                if (itr.hasNext()) {
166                    b = b.append(", ");
167                }
168            }
169            b = b.append("]");
170            return b.toString();
171        }
172    }
173
174    /**
175     * Returns a hash code for this {@code DataFormat} object.
176     * @return a hash code for this {@code DataFormat} object.
177     */
178    @Override public int hashCode() {
179        int hash = 7;
180
181        for (String id : identifier) {
182            hash = 31 * hash + id.hashCode();
183        }
184
185        return hash;
186    }
187
188    /**
189     * Indicates whether some other object is "equal to" this one.
190     * @param obj the reference object with which to compare.
191     * @return {@code true} if this object is equal to the {@code obj} argument; {@code false} otherwise.
192     */
193    @Override public boolean equals(Object obj) {
194        if (obj == null || ! (obj instanceof DataFormat)) {
195            return false;
196        }
197
198        DataFormat otherDataFormat = (DataFormat) obj;
199
200        if (identifier.equals(otherDataFormat.identifier)) {
201            return true;
202        }
203
204        return false;
205    }
206
207    /**
208     * Looks for the DataFormat which has been previously created with
209     * the given mime type as one of its ids.
210     * @param mimeType If null or the empty string, then null is returned.
211     * @return The matching DataFormat
212     */
213    public static DataFormat lookupMimeType(String mimeType) {
214        if (mimeType == null || mimeType.length() == 0) {
215            return null;
216        }
217
218        Iterator itr = DATA_FORMAT_LIST.iterator();
219        while (itr.hasNext()) {
220            DataFormat dataFormat = (DataFormat) itr.next();
221            if (dataFormat.getIdentifiers().contains(mimeType)) {
222                return dataFormat;
223            }
224        }
225        return null;
226    }
227}