简体   繁体   中英

How to copy text/html and text/plain to clipboard using Java

I need to set clipboard contents, with a java application, such that there are two MIME types available to the user. This will allow the user to paste the version of the text they want to.

I found an example that applies to JavaScript, I'm hoping that there is an equivalent for Java.

JavaScript Example:

const blob = new Blob([
    '<a href="https://stackoverflow.com/">goto stack</a>'
], { type: "text/html" });
const blobPlain = new Blob(['goto stack'], { type: "text/plain" });

navigator.clipboard.write([
    new ClipboardItem({
        [blob.type]: blob,
        [blobPlain.type]: blobPlain
    },),
])

This is essentially what I have in my Java application:

import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Clipboard;

public class tester{

 public static void main(String[] args){

     // from string to clipboard
    StringSelection selection = new StringSelection("hi");
    Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
    clipboard.setContents(selection, selection);
 }
}

I know how to set the contents, with either a "text/plain" string or a "text/html" string. The above Java example will place a plain-text string in the clipboard, it can easily be modified to put HTML formatted text in the clipboard instead - but only one or the other, not both.

If I use the following code, I can get the clipboard contents as a transferable object and then set the clipboard to that same transferable object.

@Override
    public void run() {
        try {
                Transferable trans = systemClipboard.getContents(this);
                setThisOwner(trans);
                ClipboardMonitor.sleep(sleepInterval);
            }
        } catch (Exception ex) {
            System.out.println(ex.toString());
        }
    

    private void setThisOwner(Transferable clipContents) {
        try {
            systemClipboard.setContents(clipContents, this);
        } catch (Exception ex) {
            System.out.println(ex.toString());
        }
    }

The above isn't useful so far as my question here is concerned, but the code appears to indicate to me that there should be a way to do what I want to. If I could, for example, create a custom "Transferable" and place that in "setContents()"?

Is there a way I can place both plain-text and HTML strings in the clipboard?

So, after a little bit of playing around (and reading the updated JavaDocs). The basic answer is.

  1. You need to supply both a "plain text" and "html text" value
  2. You need to supply multiple data flavours, each representing the type of data you're willing to export
  3. You need to return the appropriate data from getTransferData based on the flavour (and the flavours desired export method)

Please Note

This example exports two different strings, one is plain text and one is HTML, this is deliberate, so as it's easier to see when different text is used by different consumers. You could, obviously, use the html formatted text for both if you wished.

在此处输入图像描述

import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.util.ArrayList;
import java.util.List;

public final class Main {
    public static void main(String[] args) {

        String plainText = "Hello World";
        String htmlText = "<html><body><h1>This is a test</h1></body></html>";

        HtmlSelection htmlSelection = new HtmlSelection(htmlText, plainText);
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        clipboard.setContents(htmlSelection, null);
    }

    public static class HtmlSelection implements Transferable {

        private static List<DataFlavor> htmlFlavors = new ArrayList<>(3);

        static {
                htmlFlavors.add(DataFlavor.stringFlavor);
                htmlFlavors.add(DataFlavor.allHtmlFlavor);
        }

        private String html;
        private String plainText;

        public HtmlSelection(String html, String plainText) {
            this.html = html;
            this.plainText = plainText;
        }

        public DataFlavor[] getTransferDataFlavors() {
            return (DataFlavor[]) htmlFlavors.toArray(new DataFlavor[htmlFlavors.size()]);
        }

        public boolean isDataFlavorSupported(DataFlavor flavor) {
            return htmlFlavors.contains(flavor);
        }

        public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {

            String toBeExported = plainText;
            if (flavor == DataFlavor.stringFlavor) {
                toBeExported = plainText;
            } else if (flavor == DataFlavor.allHtmlFlavor) {
                toBeExported = html;
            }

            if (String.class.equals(flavor.getRepresentationClass())) {
                return toBeExported;
            }
            throw new UnsupportedFlavorException(flavor);
        }
    }
}

You should also beware that some applications may prefer a different method of export (ie via a Reader or InputStream ), this is demonstrated in...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM