source: josm/trunk/src/org/openstreetmap/josm/gui/datatransfer/ClipboardUtils.java@ 11921

Last change on this file since 11921 was 11921, checked in by Don-vip, 7 years ago

improve unit test coverage of utilities classes thanks to https://trajano.github.io/commons-testing

File size: 6.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.datatransfer;
3
4import java.awt.GraphicsEnvironment;
5import java.awt.HeadlessException;
6import java.awt.Toolkit;
7import java.awt.datatransfer.Clipboard;
8import java.awt.datatransfer.ClipboardOwner;
9import java.awt.datatransfer.DataFlavor;
10import java.awt.datatransfer.StringSelection;
11import java.awt.datatransfer.Transferable;
12import java.awt.datatransfer.UnsupportedFlavorException;
13import java.io.IOException;
14
15import org.openstreetmap.josm.Main;
16import org.openstreetmap.josm.gui.util.GuiHelper;
17import org.openstreetmap.josm.tools.Utils;
18
19/**
20 * This is a utility class that provides methods useful for general data transfer support.
21 *
22 * @author Michael Zangl
23 * @since 10604
24 */
25public final class ClipboardUtils {
26 private static final class DoNothingClipboardOwner implements ClipboardOwner {
27 @Override
28 public void lostOwnership(Clipboard clpbrd, Transferable t) {
29 // Do nothing
30 }
31 }
32
33 private static Clipboard clipboard;
34
35 private ClipboardUtils() {
36 // Hide default constructor for utility classes
37 }
38
39 /**
40 * This method should be used from all of JOSM to access the clipboard.
41 * <p>
42 * It will default to the system clipboard except for cases where that clipboard is not accessible.
43 * @return A clipboard.
44 * @see #getClipboardContent()
45 */
46 public static synchronized Clipboard getClipboard() {
47 // Might be unsupported in some more cases, we need a fake clipboard then.
48 if (clipboard == null) {
49 try {
50 clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
51 } catch (HeadlessException e) {
52 Main.warn("Headless. Using fake clipboard.", e);
53 clipboard = new Clipboard("fake");
54 }
55 }
56 return clipboard;
57 }
58
59 /**
60 * Gets the singleton instance of the system selection as a <code>Clipboard</code> object.
61 * This allows an application to read and modify the current, system-wide selection.
62 * @return the system selection as a <code>Clipboard</code>, or <code>null</code> if the native platform does not
63 * support a system selection <code>Clipboard</code> or if GraphicsEnvironment.isHeadless() returns true
64 * @see Toolkit#getSystemSelection
65 */
66 public static Clipboard getSystemSelection() {
67 if (GraphicsEnvironment.isHeadless()) {
68 return null;
69 } else {
70 return Toolkit.getDefaultToolkit().getSystemSelection();
71 }
72 }
73
74 /**
75 * Gets the clipboard content as string.
76 * @return the content if available, <code>null</code> otherwise.
77 */
78 public static String getClipboardStringContent() {
79 try {
80 Transferable t = getClipboardContent();
81 if (t != null && t.isDataFlavorSupported(DataFlavor.stringFlavor)) {
82 return (String) t.getTransferData(DataFlavor.stringFlavor);
83 }
84 } catch (UnsupportedFlavorException | IOException ex) {
85 Main.error(ex);
86 }
87 return null;
88 }
89
90 /**
91 * Extracts clipboard content as {@code Transferable} object. Using this method avoids some problems on some platforms.
92 * @return The content or <code>null</code> if it is not available
93 */
94 public static synchronized Transferable getClipboardContent() {
95 return getClipboardContent(getClipboard());
96 }
97
98 /**
99 * Extracts clipboard content as {@code Transferable} object. Using this method avoids some problems on some platforms.
100 * @param clipboard clipboard from which contents are retrieved
101 * @return clipboard contents if available, {@code null} otherwise.
102 */
103 public static Transferable getClipboardContent(Clipboard clipboard) {
104 Transferable t = null;
105 for (int tries = 0; t == null && tries < 10; tries++) {
106 try {
107 t = clipboard.getContents(null);
108 } catch (IllegalStateException e) {
109 // Clipboard currently unavailable.
110 // On some platforms, the system clipboard is unavailable while it is accessed by another application.
111 Main.trace("Clipboard unavailable.", e);
112 try {
113 Thread.sleep(1);
114 } catch (InterruptedException ex) {
115 Main.warn(ex, "InterruptedException in " + Utils.class.getSimpleName()
116 + " while getting clipboard content");
117 Thread.currentThread().interrupt();
118 }
119 } catch (NullPointerException e) { // NOPMD
120 // JDK-6322854: On Linux/X11, NPE can happen for unknown reasons, on all versions of Java
121 Main.error(e);
122 }
123 }
124 return t;
125 }
126
127 /**
128 * Copy the given string to the clipboard.
129 * @param s The string to copy.
130 * @return True if the copy was successful
131 */
132 public static boolean copyString(String s) {
133 return copy(new StringSelection(s));
134 }
135
136 /**
137 * Copies the given transferable to the clipboard. Handles state problems that occur on some platforms.
138 * @param transferable The transferable to copy.
139 * @return True if the copy was successful
140 */
141 public static boolean copy(final Transferable transferable) {
142 return GuiHelper.runInEDTAndWaitAndReturn(() -> {
143 try {
144 getClipboard().setContents(transferable, new DoNothingClipboardOwner());
145 return Boolean.TRUE;
146 } catch (IllegalStateException ex) {
147 Main.error(ex);
148 return Boolean.FALSE;
149 }
150 });
151 }
152
153 /**
154 * Returns a new {@link DataFlavor} for the given class and human-readable name.
155 * @param c class
156 * @param humanPresentableName the human-readable string used to identify this flavor
157 * @return a new {@link DataFlavor} for the given class and human-readable name
158 * @since 10801
159 */
160 public static DataFlavor newDataFlavor(Class<?> c, String humanPresentableName) {
161 try {
162 return new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + ";class=" + c.getName(),
163 humanPresentableName, c.getClassLoader());
164 } catch (ClassNotFoundException e) {
165 throw new IllegalArgumentException(e);
166 }
167 }
168}
Note: See TracBrowser for help on using the repository browser.