Wie kann man auf die System-Zwischenablage zugreifen?

Mit Hilfe der Klasse java.awt.datatransfer.Clipboard und der Schnittstelle java.awt.datatransfer.Transferable kann auf die System-Zwischenablage und deren Funktionen zugegriffen werden.

Die Klasse Clipboard stellt Mechanismen bereit, die durch Kopieren/Ausschneiden/Einfügen eine Datenübertrag in die oder aus der System-Zwischenablage ermöglichen. Das folgende Beispiel demonstriert das Einfügen eines Strings in die Zwischenablage und deren Auslesen.

public class Zwischenablage {

    private final static int DELAY = 8000; // ms

    public static void main(String[] args) {
        copyToClip("Inhalt der Zwischenablage");
    }
    
    private static void copyToClip(String s) {
        Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard();
        StringSelection sel;

        if (s.length() > 0) {
            sel = new StringSelection(s);
        } else {
            return;
        }

        clip.setContents(sel, sel);

        // Ausgabe
        Transferable t = clip.getContents(null);
        if (t.isDataFlavorSupported(DataFlavor.stringFlavor)) {
            try {
                String ausgabe = (String) t.getTransferData(DataFlavor.stringFlavor);
                System.out.println(ausgabe);
            } catch (UnsupportedFlavorException | IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Ein Clipboard-Objekt der System-Zwischenablage kann durch die Methode getSystemClipboard() der Klasse java.awt.Toolkit erhalten werden. Ein String kann der Zwischenablage jedoch nicht direkt hinzugefügt werden, sondern muss in einem Objekt des Typs StringSelection gekapselt werden, das die Übertragungsfunktionalität bereitstellt. Dies geschieht hier nach Prüfen der Stringlänge. Durch setContents() wird es dann dem Clipboard-Objekt hinzugefügt. Die Methode verlangt neben dem eigentlichen Inhalt in Form eines Transferable (StringSelection implementiert Transferable) als zweites Argument noch eine Instanz vom Typ ClipboardOwner, die als Eigner des übergebenen Inhalts eingetragen wird. Da StringSelection neben Transferable auch ClipboardOwner implementiert, kann hierzu die selbe Instanz verwendet werden.

Das Abrufen des Inhalts aus der Zwischenablage geschieht durch die Methode getContents(), die ein Objekt vom Typ Object als Argument erwartet. Seine Nutzung wurde noch nicht implementiert und kann somit null sein. Als Rückgabe liefert die Methode ein Transferable. Vor Extraktion des Clipboard-Inhalts muss der Inhaltstyp des Transferable, der sog. DataFlavor, überprüft werden. getTransferData() liefert dann ein Objekt des spezifizierten DataFlavour, das hier zum String gecastet werden kann.

Leeren der Zwischenablage

Die Frage des Leerens der System-Zwischenablage ist nicht trivial. Es muss bedacht werden, dass, je nach Betriebssystem, der Zugriff auch auf vergangene Einträge durchaus möglich ist. Das Einbinden der Zwischenablage in sicherheitsrelevante Anwendungen sollte möglichst vermieden werden. Dennoch kann es an der einen oder anderen Stelle sinnvoll sein, die Zwischenablage zu leeren, genauer, einen vorhandenen Eintrag durch einen Leereintrag zu ersetzen1.
Das folgende Beispiel erzeugt ein leeres Transferable das der Zwischenablage übergeben werden kann.

class EmptyObject implements Transferable {

    @Override
    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
        return null;
    }

    @Override
    public DataFlavor[] getTransferDataFlavors() {
        return null;
    }

    @Override
    public boolean isDataFlavorSupported(DataFlavor flavor) {
        return false;
    }
}

//...

clip.setContents(new EmptyObject(), null);

Auch die Übergabe eines Leerstrings ist natürlich möglich:

StringSelection sel = new StringSelection("");
clip.setContents(sel, null);

Soll der aktuelle Eintrag der Zwischenablage nach einem vorgegebenen Intervall überschrieben werden, kann dies innerhalb eines eigenen Threads geschehen. Das folgende Beispiel fasst das bislang Gesagte zusammen und ersetzt den Inhalt der Zwischenablage nach 8 Sekunden.

public class Zwischenablage {

    private final static int DELAY = 8000; // ms

    public static void main(String[] args) {
        copyToClip("Inhalt der Zwischenablage");
    }

    private static void copyToClip(String s) {
        Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard();
        StringSelection sel;

        if (s.length() > 0) {
            sel = new StringSelection(s);
        } else {
            return;
        }

        clip.setContents(sel, sel);

        new Thread() {
            public void run() {
                try {
                    Thread.sleep(DELAY);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                clip.setContents(new EmptyObject(), null);
            }
        }.start();
    }
}

1) Mit JavaFX ist ein vollständiges Leeren der Zwischenablage möglich. Die Klasse javafx.scene.input.Clipboard definiert hierzu die Methode clear().