Clipboard

KonradN

Super-Moderator
Mitarbeiter
Daten im Clipboard (aus Java Sicht) sind nicht einfach nur Daten sondern Daten mit einem DataFlavor. Und man kann Daten dann ggf. in diversen Dataflavor abfragen. (Das kennt man ja - man nimmt Daten mit Formatierungen in die Zwischenablage und dann wird irgendwo nur der Text eingetragen.

 

vup

Mitglied
wie Fonts usw. kopieren
Wenn du von Fonts sprichst, meinst du dann damit RichText? Das ist letztlich auch nur Plaintext mit bestimmten Formatierungsanweisungen, also ein String... Beispiel:

Code:
{\rtf1
Guten Tag!
\line
{\i Dies} ist \b{\i ein
\i0 formatierter \b0Text}.
\par
\b Das \b0Ende.
}

Weitere Hinweise dazu bei Wikipedia.
 

Neumi5694

Top Contributor
Schlimmstenfalls, falls du wirklich keine Ahnung hast, was sich da eigentlich gerade in der Zwischenablage befeindet, kannst du dir ja auch einfach alles mal ausgeben lassen, inklusive der Flavors und anderen Eigenschaften, die Konrad genannt hat.
Einfach mal ausprobieren.
 

NicoHatProbleme2

Bekanntes Mitglied
Wenn du von Fonts sprichst, meinst du dann damit RichText? Das ist letztlich auch nur Plaintext mit bestimmten Formatierungsanweisungen, also ein String... Beispiel:

Code:
{\rtf1
Guten Tag!
\line
{\i Dies} ist \b{\i ein
\i0 formatierter \b0Text}.
\par
\b Das \b0Ende.
}

Weitere Hinweise dazu bei Wikipedia.
Ich meinte eigentlich java.awt.Font
 

KonradN

Super-Moderator
Mitarbeiter
Also bei diesen ganzen Dingen ist immer die Frage: Was muss man denn im Clipboard ablegen?

Oder anders formuliert: Clipboard ist auf den Rechner begrenzt, daher ist die Frage: Muss man alle Informationen ablegen oder liegen die Daten nicht schon vor? Bestes Beispiel ist eine Datei: Muss man eine große Datei komplett in den Speicher laden um dann den Dateiinhalt in das Clipboard zu kopieren oder eicht nicht einfach die Information: "Hey - es geht um die Datei unter dem folgenden Pfad: ......"

Und das ist auch hier genau so: Die Font ist ja in der Regel auf dem System bekannt. Daher reicht es aus, einfach die Details der Font, die zum laden benötigt werden, weiter zu geben. Das kann dann etwas sein wie:
font.getFontName() / font.getStyle() / font.getSize()

Das kann man dann noch irgendwie verpacken - dann baut man sich ein Format, dass man so erkennen kann. Also von mir aus etwas analog zu dem jdbc:....
Dann hat man von mir aus: "font:" + font.getFontName() + "/" + font.getStyle() + "/" + font.getSize()

Und das kann man dann auch wieder auswerten. Fängt der Text im clipboard mit "font:" an?

Das kann man sich natürlich noch beliebig überlegen. Man kann sich ggf. auch stärker Richtung URL / URI orientieren. Dann hat man eine URL mit font:// statt eben dem http://.

Wie heisst es so schön: "The stage is yours!" - Du kannst Dich hier also frei entfalten.

An der Stelle ansonsten einfach einmal - mit netten Grüßen von ChatGPT / GPT-4 - ein Codebeispiel, wie es aussehen könnte (ohne das font: oder so - einfach mit | als Trenner:

Java:
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;

public class FontClipboardExample {

    public static void main(String[] args) {
        // Create a Font object
        Font font = new Font("Arial", Font.PLAIN, 12);

        // Store the Font object to the clipboard
        storeFontToClipboard(font);

        // Read the Font object from the clipboard
        Font retrievedFont = readFontFromClipboard();
        if (retrievedFont != null) {
            System.out.println("Retrieved Font: " + retrievedFont);
        } else {
            System.out.println("No Font found in clipboard");
        }
    }

    public static void storeFontToClipboard(Font font) {
        String fontString = font.getFontName() + "|" + font.getStyle() + "|" + font.getSize();
        StringSelection stringSelection = new StringSelection(fontString);
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        clipboard.setContents(stringSelection, null);
    }

    public static Font readFontFromClipboard() {
        try {
            Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
            Transferable contents = clipboard.getContents(null);
            String fontString = (String) contents.getTransferData(DataFlavor.stringFlavor);

            String[] fontData = fontString.split("\\|");
            String fontName = fontData[0];
            int fontStyle = Integer.parseInt(fontData[1]);
            int fontSize = Integer.parseInt(fontData[2]);

            return new Font(fontName, fontStyle, fontSize);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
 

KonradN

Super-Moderator
Mitarbeiter
Also die Lösung mit den Fomnts ist relativ generisch. Über die hinterlegten Daten sollte man die Font auch in anderen Sprachen laden können. Also prinzipiell könnte man ein C++ Programm schreiben, dass die Informationen aus dem Clipboard lädt und dann die Font erzeugt.

Aber das ist ggf. nicht zwingend eine Notwendigkeit - evtl. will man einfach eine Zwischenablage haben, in der mal beliebige Elemente serialisieren kann. Das ist dann auf Java und ggf. die eigene Applikation begrenzt.

Das würde also bedeuten, dass man einfach beliebige Daten serializieren möchte und in die Zwischenablage ablegen möchte. Das könnte dann eine Lösung sein wie:
Es wird abgelegt: serialized://<classname>/<data>

Serialisieren kann man mit den ObjectStreams, classname ist dabei eigentlich unnötig, da die Information bereits in den serialisierten Daten enthalten ist. Aber da es nicht sichtbar ist, habe ich es einmal hinzugefügt, damit die Zwischenablage auch für Menschen lesbarer wird.

Wenn man etwas serialisiert, dann hat man halt wirkliche binary Daten. Um das als String zu haben, muss man es kodieren - das kann per Base64 erfolgen.

Um die Idee etwas zu visualisieren, einfach auch einmal etwas von ChatGPT erzeugter Code (mit Fehlerbehebung - ChartGPT hatte hier paar mehr Probleme):
Java:
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Base64;

public class SerializableClipboardExample {

    public static void main(String[] args) {
        // Create a Font object
        Font font = new Font("Arial", Font.PLAIN, 12);

        // Store the Font object to the clipboard
        storeObjectToClipboard(font);

        // Read the Font object from the clipboard
        Font retrievedFont = (Font) readObjectFromClipboard();
        if (retrievedFont != null) {
            System.out.println("Retrieved Font: " + retrievedFont);
        } else {
            System.out.println("No Font found in clipboard");
        }
    }

    public static void storeObjectToClipboard(Serializable object) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(object);
            oos.close();
            String data = Base64.getEncoder().encodeToString(baos.toByteArray());
            String clipboardString = "serialized://" + object.getClass().getName() + "/" + data;
            StringSelection stringSelection = new StringSelection(clipboardString);
            Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
            clipboard.setContents(stringSelection, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Object readObjectFromClipboard() {
        try {
            Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
            Transferable contents = clipboard.getContents(null);
            String clipboardString = (String) contents.getTransferData(DataFlavor.stringFlavor);

            if (clipboardString.startsWith("serialized://")) {
                String[] parts = clipboardString.split("/", 4);
                String className = parts[2];
                String data = parts[3];
                byte[] decodedData = Base64.getDecoder().decode(data);
                ByteArrayInputStream bais = new ByteArrayInputStream(decodedData);
                ObjectInputStream ois = new ObjectInputStream(bais);
                Object retrievedObject = ois.readObject();
                ois.close();
                return retrievedObject;
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

Edit: className wurde falsch gesetzt - das ist natürlich Element 2 und nicht 1. War mir nur nicht auf Anhieb aufgefallen, da es einfach nicht weiter vewendet wurde.
 
Zuletzt bearbeitet:

NicoHatProbleme2

Bekanntes Mitglied
Ich dachte schon daran, das zu serialisieren, doch weiß ich, dass man bei Word Buchstaben mit Formatierung kopieren kann, die man überall normalformatiert einfügen kann, doch die bei Word eine Formatierung besitzen. deshalb dachte ich mir, dass das wohl irgendwie möglich sein könnte und wollte dies auch bei meinem Schreibprogramm einfügen
 

Neumi5694

Top Contributor
Da kommen die Flavors ins Spiel.
Die Zwischenablage beinhaltet mehr als einen Datensatz, einmal den formatierten und einmal den unformatierten. Die entsprechenden Anwendungen holen sich dann raus, was sie brauchen.
Hier haben sich schon ein paar andere damit beschäftigt:
 

KonradN

Super-Moderator
Mitarbeiter
In #4 sind auch schon erste die Links zu den entsprechenden Klassen DataFlavor und co. Das kann man sich in Ruhe ansehen und damit herum spielen.

Zum Rumspielen kann auch ChatGPT interessant sein um da diverse Codes erstellt zu bekommen.
Nur einmal kurz aufgezeigt, wie man da heran gehen könnte:

Anfrage: "how can i store data in the clipboard in multiple dataflavors using java"

Die Antwort als Ganzes ist recht umfangreich - ich kürze diese auf den Kernpunkt: Das Transferable, das man setzen muss:
Java:
Transferable transferable = new Transferable() {
    @Override
    public DataFlavor[] getTransferDataFlavors() {
        return new DataFlavor[] {
            DataFlavor.stringFlavor,
            DataFlavor.imageFlavor,
            // Add more data flavors here
        };
    }

    @Override
    public boolean isDataFlavorSupported(DataFlavor flavor) {
        return Arrays.asList(getTransferDataFlavors()).contains(flavor);
    }

    @Override
    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
        if (flavor.equals(DataFlavor.stringFlavor)) {
            return "Hello, World!";
        } else if (flavor.equals(DataFlavor.imageFlavor)) {
            return ImageIO.read(new File("image.jpg"));
        }
        // Add more cases for each data flavor here
        throw new UnsupportedFlavorException(flavor);
    }
};

Daran kann man schon fast alles erkennen.
 

Ähnliche Java Themen


Oben