Java has java.awt.datatransfer.Clipboard for manipulating the clipboard. Classes are available. The details are written by Mr. Hishidama, so please read that article.
Hishidama's Technical Memo Page-Clipboard
I'm the Clipboard API in JavaFX [javafx.scene.input.Clipboard](https://docs.oracle.com/javase/jp/8/javafx/api/javafx/scene/input/Clipboard I decided to look at .html).
Java SE | 1.8.0_u131 |
---|---|
OS | Windows 10 |
IDE | IntelliJ IDEA 2017.1.3 |
Represents an operating system clipboard where data can be placed during operations such as cut, copy, and paste.
Well, it's a class that can do all sorts of clipboard related things.
Let's try! I will try to write the code.
Code that exits with an exception when executed
import javafx.scene.input.Clipboard;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
final Clipboard cb = Clipboard.getSystemClipboard();
System.out.println(cb.getString());;
}
}
As you can see from the package hierarchy, javafx.scene.input.Clipboard is a JavaFX class and is not available to regular threads.
Exception in thread "main" java.lang.IllegalStateException: This operation is permitted on the event thread only; currentThread = main
at com.sun.glass.ui.Application.checkEventThread(Application.java:443)
at com.sun.glass.ui.ClipboardAssistance.<init>(ClipboardAssistance.java:40)
at com.sun.javafx.tk.quantum.QuantumToolkit.getSystemClipboard(QuantumToolkit.java:1200)
at javafx.scene.input.Clipboard.getSystemClipboardImpl(Clipboard.java:413)
at javafx.scene.input.Clipboard.getSystemClipboard(Clipboard.java:178)
at jp.toastkid.sandbox.Sandbox.main(Sandbox.java:10)
So, if you want to operate the clipboard in a normal application, use java.awt.datatransfer.Clipboard. ~~ End ~~
Since it can be used in any JavaFX application, make the class of the main method a subclass of javafx.application.Application.
Code that works fine
import javafx.application.Application;
import javafx.scene.input.Clipboard;
import javafx.stage.Stage;
public class MainFx extends Application {
public static void main(String[] args) {
Application.launch(SandboxFx.class);
}
@Override
public void start(Stage primaryStage) throws Exception {
Clipboard cb = Clipboard.getSystemClipboard();
System.out.println(cb.getString());
}
}
Running this code will output the string currently held in the clipboard.
final Clipboard cb = Clipboard.getSystemClipboard();
System.out.println(cb.getString());
getContentTypes() Gets the type of content that is being held.
getContentTypes()
System.out.println(cb.getContentTypes());
[[text/uri-list], [JAVA_DATAFLAVOR:application/x-java-jvm-local-objectref; class=com.intellij.codeInsight.editorActions.FoldingData], [text/plain], [ms-stuff/oem-text], [text/rtf], [text/html], [ms-stuff/locale]]
[[FileName], [message/external-body;access-type=clipboard;index=1;size=28453;name="650contribution.png "], [AsyncFlag], [DataObjectAttributesRequiringElevation], [application/x-java-file-list, java.file-list], [FileNameW], [ms-stuff/preferred-drop-effect], [message/external-body;access-type=clipboard;index=2;size=220376;name="sample_images_1.jpg "], [text/uri-list], [message/external-body;access-type=clipboard;index=0;size=119242;name="sample_images_2.jpg "], [Shell Object Offsets], [Shell IDList Array], [DataObjectAttributes]]
[[text/uri-list], [application/x-java-rawimage], [text/_moz_htmlinfo], [text/html;cf=49474], [application/x-java-file-list, java.file-list], [text/_moz_htmlcontext], [application/x-moz-nativeimage], [text/html], [application/x-moz-file-promise-url], [application/x-moz-file-promise-dest-filename], [cf17], [ms-stuff/preferred-drop-effect]]
hasXX() Determines the type of content you are holding.
hasXX()Code to try
System.out.println(cb.hasString());
System.out.println(cb.hasUrl());
System.out.println(cb.hasHtml());
System.out.println(cb.hasRtf());
System.out.println(cb.hasImage());
System.out.println(cb.hasFiles());
T: true F: false
Method name | Text | Local image file | Web image file | URL on Browser |
---|---|---|---|---|
hasString() | T | F | F | T |
hasUrl() | T | T | T | F |
hasHtml() | T | F | T | F |
hasRtf() | T | F | F | F |
hasImage() | F | F | T | F |
hasFiles() | F | T | T | F |
setContent(Map<DataFormat, Object>) Not only can you retrieve the value, you can also plug it in. Use Map and DataFormat for merging. Dat ** a ** Format. Please note the name.
final Map<DataFormat, Object> content = new HashMap<>();
content.put(DataFormat.PLAIN_TEXT, "Orange");
cb.setContent(content);
If you press Ctrl + V on a text editor after running the application, the text "Orange" will be pasted.
But what if we have multiple values in the content?
final Map<DataFormat, Object> content = new HashMap<>();
content.put(DataFormat.URL, "https://www.yahoo.co.jp");
content.put(DataFormat.PLAIN_TEXT, "Toast");
cb.setContent(content);
If you press Ctrl + V on a text editor after running the application, the text "Toast" will be pasted. It seems that only one can be kept in the clipboard.
clear() This Clipboard API has a clear method.
Clipboard.clear()
System.out.println(clipboard.getString());
clipboard.clear();
System.out.println(clipboard.getString());
Execution result
holding text
null
Since it is a JavaFX API, its use is inevitably combined with a GUI.
Well, that's it.
As the name implies, multi-clipboard is a function that can hold multiple values in the clipboard, and it seems that it is a standard function of UNIX text editors. What would happen if I talked to people about this function in a roundabout way? "Productive Programmer" had such a story.
You might end up being told by a man wearing sandals, "I've been using it for 20 years since high school," for about an hour.
For example, if the image is retained, it will be automatically saved to a file, or if it is a URL, a WebView window will be displayed ...
So, I tried to implement a very simple one. The source code can be found in the following repository on GitHub.
https://github.com/toastkidjp/clipboard_observer_app/tree/qiita
It's a sloppy GUI application that displays a string or image held in the clipboard in a window and clicks on them to re-hold them in the clipboard.
Since javafx.scene.input.Clipboard does not have a reactive API such as an event listener, I implemented it by using RxJava to check the contents at 1-second intervals.
Observable to monitor the clipboard
Observable.interval(1, TimeUnit.SECONDS)
.observeOn(JavaFxScheduler.platform())
.map(l -> getStringOrEmpty())
.filter(str -> !str.isEmpty())
.subscribe(stringConsumer, Throwable::printStackTrace);
The RxJava Scheduler provided by RxJavaFX allows JavaFX application threads to execute processing in RxJava. I will. [Platform.runLater (Runnable)](https://docs.oracle.com/javase/jp/8/javafx/api/javafx/application/Platform.html#runLater-] which is prepared as standard for Consumer etc. You can use java.lang.Runnable-), but if you have to return a value like map or filter, this JavaFxScheduler is useful.
In RxJava2, returning null in map will result in a NullPointerException.
java.lang.NullPointerException: The mapper function returned a null value.
at io.reactivex.internal.functions.ObjectHelper.requireNonNull(ObjectHelper.java:39)
at io.reactivex.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:59)
at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:200)
at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:252)
at io.reactivex.rxjavafx.schedulers.JavaFxScheduler$JavaFxWorker$QueuedRunnable.run(JavaFxScheduler.java:87)
at io.reactivex.rxjavafx.schedulers.JavaFxScheduler$JavaFxWorker.run(JavaFxScheduler.java:158)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:748)
To avoid this, we provide an Empty object.
private static final Image EMPTY_IMAGE = new WritableImage(1, 1);
I introduced JavaFX's Clipboard API and explained how to implement a simple application using it. If you are not creating a JavaFX application, not here java.awt.datatransfer.Clipboard. The JavaFX Clipboard API has a clear () method.