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

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

sonar - fb-contrib:NAB_NEEDLESS_BOOLEAN_CONSTANT_CONVERSION - Performance - Method needlessly boxes a boolean constant

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