我自定义的“从剪贴板粘贴”行动 [英] My custom "paste from clipboard" action

查看:498
本文介绍了我自定义的“从剪贴板粘贴”行动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想找到一种方法来做自定义从剪贴板粘贴操作。让我们假设剪贴板的内容是文本为简单(不是一个文件)。每当您按 Ctrl + V 时,它会将该内容(即文本)插入到具有焦点的当前打开文件。



我有一个应用程式可以使用全域热键。请注意,这不是一个窗口应用程序,它是一个控制台应用程序,它捕获热键全局。假设我有 Ctrl + U 的热键。所以我想做的是当我按 Ctrl + U 我想插入一些预定义的文本到当前打开的文件。就像 Ctrl + V 可以!与标准 Ctrl + V 的差异是我要插入预定义文本,热键为不同



我该如何做?



我更喜欢跨平台的解决方案,但首先我要为Linux,特别是Ubuntu做这个。语言不重要,但Java或Scala会更好。当然,我知道解决方案是Java使用本机操作系统的API。

解决方案

我希望这个hackish解决方案将工作,但它仍然未经测试,我不确定如何捕获的热键的事件。



这个代码的背后的想法是以下五个步骤:

  • 将预定义的文本粘贴到剪贴板中
  • / li>
  • 触发全局粘贴事件

  • 释放全局粘贴事件

  • 将剪贴板重置为旧文本

  • 这应该给出一个新的剪贴板的外观(如果没有,希望它能激发你提出一个更好, 。



    不用多说,这里是我的代码。首先我有一个简单的帮助方法来设置剪贴板的值(我们这样做两次)。

      public static void setClipboard (String s){
    StringSelection contents = new StringSelection(s);
    Clipboard clipboard = Toolkit.getDefaultToolkit()。getSystemClipboard();
    clipboard.setContents(contents,contents);
    }

    然后,我有一个主要方法,

      public static void main(String [] args){

    // Step 1)获取旧文本
    String oldText =;
    try {
    oldText =(String)Toolkit.getDefaultToolkit()。getSystemClipboard()。getData(DataFlavor.stringFlavor);
    } catch(UnsupportedFlavorException ufe){
    ufe.printStackTrace();
    } catch(IOException ioe){
    ioe.printStackTrace();
    }

    //步骤2)将我们的文本粘贴到剪贴板
    setClipboard(这个lorem ipsum预定义字符串吹了我的心。

    //步骤3)触发粘贴事件
    机器人robot = null;
    try {
    robot = new Robot();
    } catch(AWTException awte){
    awte.printStackTrace();
    }
    robot.keyPress(KeyEvent.VK_CONTROL);
    robot.keyPress(KeyEvent.VK_V);

    //步骤4)释放粘贴事件
    robot.keyRelease(KeyEvent.VK_CONTROL);
    robot.keyRelease(KeyEvent.VK_V);

    //步骤5)重置剪贴板
    setClipboard(oldText);

    }



    这里是一些代码来测试什么样的内容在剪贴板 - 图像,文本等。unicode错误来自这样的事实,剪贴板的旧内容是不能由纯String表示。要修复此错误,您必须检查旧内容是否是图片,旧内容是否为文本,并相应地保存。

      public static int kindOfContents(){
    剪贴板剪贴板= Toolkit.getDefaultToolkit()。getSystemClipboard();
    可传输内容= clipboard.getContents(null);

    if(contents.isDataFlavorSupported(DataFlavor.stringFlavor)){
    //字符串,临时保存为字符串并回写为字符串
    return 0;
    } else if(contents.isDataFlavorSupported(DataFlavor.imageFlavor)){
    // Image,暂时保存为BufferedImage并回写为image
    return 1;
    } else if(contents.isDataFlavorSupported(DataFlavor.javaFileListFlavor)){
    //文件列表,临时保存为java.util.List接口并回写为文件列表
    return 2 ;
    }

    }

    如果内容是文本

      //步骤1)获取旧文本
    String oldText =;
    try {
    oldText =(String)Toolkit.getDefaultToolkit()。getSystemClipboard()。getData(DataFlavor.stringFlavor);
    } catch(UnsupportedFlavorException ufe){
    ufe.printStackTrace();
    } catch(IOException ioe){
    ioe.printStackTrace();
    }

    //步骤5)重置剪贴板
    setClipboard(oldText);

    但是,如果内容是图像,则要暂时保存并重写,需要执行以下操作。请注意,用于编写图片的代码不是我的,而是来自设置图片的接受答案剪贴板 - Java

      //步骤1)获取旧图像
    BufferedImage img = null;
    try {
    img =(BufferedImage)Toolkit.getDefaultToolkit()。getSystemClipboard()。getData(DataFlavor.imageFlavor);
    } catch(UnsupportedFlavorException ufe){
    ufe.printStackTrace();
    } catch(IOException ioe){
    ioe.printStackTrace();
    }

    取自将图片设置为剪贴板 - Java

      /步骤5)重置剪贴板
    ImageTransferable transferable = new ImageTransferable(image);
    Toolkit.getDefaultToolkit()。getSystemClipboard()。setContents(transferable,null);

    static class ImageTransferable implements Transferable
    {
    private Image image;

    public ImageTransferable(Image image)
    {
    this.image = image;
    }

    public Object getTransferData(DataFlavor flavor)
    throws UnsupportedFlavorException
    {
    if(isDataFlavorSupported(flavor))
    {
    return image;
    }
    else
    {
    throw new UnsupportedFlavorException(flavor);
    }
    }

    public boolean isDataFlavorSupported(DataFlavor flavor)
    {
    return flavor == DataFlavor.imageFlavor;
    }

    public DataFlavor [] getTransferDataFlavors()
    {
    return new DataFlavor [] {DataFlavor.imageFlavor};
    }
    }


    I want to find a way to do kind of a custom "paste from clipboard" action. Let's assume the content of clipboard is text for simplicity (not a file). Whenever you press Ctrl+V, it inserts that content (which is text) to a current open file which has a focus.

    I have an app for catching a global hotkey. Note this is not a window application, it's a console one and it catches the hotkey globally. Let's say I have the hotkey of Ctrl+U. So what I want to do is when I press Ctrl+U I want to insert some predefined text to a current open file. Just like Ctrl+V does! The differences from a standard Ctrl+V is that I want to insert a predefined text and the hotkey is different.

    How do I do this?

    I'd prefer a cross-platform solution, however first of all I'm going to do that for Linux, specifically Ubuntu. The language is not important but Java or Scala would be better. Of course, I understand that the solutions is Java uses native OS' API for that.

    解决方案

    I'm hoping that this hackish solution would work, but it is still untested, I am unsure how to catch the event for the hotkey.

    The idea behind this code is the following five steps:

    1. Get the old text in the clipboard and temporarily save it
    2. Paste our predefined text into the clipboard
    3. Trigger the global paste event
    4. Release the global paste event
    5. Reset the clipboard to the old text

    This should give the appearance of a new clipboard (if not, hopefully it inspires you to come up with a better, less hackish solution).

    Without further ado, here is my code. First I have a simple helper method to set the value of the clipboard (as we do this twice).

    public static void setClipboard(String s) {
        StringSelection contents = new StringSelection(s);
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        clipboard.setContents(contents, contents);
    }
    

    And then, I have a main method where I go through the five steps in order.

    public static void main(String[] args) {
    
        // Step 1 ) get old text
        String oldText = "";
        try {
            oldText = (String) Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor); 
        } catch (UnsupportedFlavorException ufe) {
            ufe.printStackTrace();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    
        // Step 2 ) paste our text in clipboard
        setClipboard("This lorem ipsum predefined string blows my mind.");
    
        // Step 3 ) trigger paste event
        Robot robot = null;
        try {
            robot = new Robot();
        } catch (AWTException awte) {
            awte.printStackTrace();
        }
        robot.keyPress(KeyEvent.VK_CONTROL);
        robot.keyPress(KeyEvent.VK_V);
    
        // Step 4 ) Release paste event
        robot.keyRelease(KeyEvent.VK_CONTROL);
        robot.keyRelease(KeyEvent.VK_V);
    
        // Step 5 ) Reset clipboard
        setClipboard(oldText);
    
    }
    

    [Edit]:

    Here is some code to test what kind of contents are in the Clipboard - image, text, etc. The unicode error was coming from the fact that the old contents of the clipboard were something that couldn't be represented by a plain String. To fix this error, you will have to check if the old contents were an image, the old contents were text, and save them accordingly.

    public static int kindOfContents() {
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        Transferable contents = clipboard.getContents(null);
    
        if(contents.isDataFlavorSupported(DataFlavor.stringFlavor)) {
            // String, save temporarily as string and write back as string
            return 0;
        } else if(contents.isDataFlavorSupported(DataFlavor.imageFlavor)) {
            // Image, save temporarily as BufferedImage and write back as image
            return 1;
        } else if(contents.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
            // List of files, save temporarily as java.util.List interface and write back as the file lists
            return 2;
        }
    
    }
    

    If the contents are text, then for saving and writing the content you would use the old method, repasted below for convenience.

    // Step 1 ) get old text
    String oldText = "";
    try {
        oldText = (String) Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor); 
    } catch (UnsupportedFlavorException ufe) {
        ufe.printStackTrace();
    } catch (IOException ioe) {
        ioe.printStackTrace();
    }
    
    // Step 5 ) Reset clipboard
    setClipboard(oldText);
    

    However, if the contents are an image, then for saving temporarily and rewriting you need to do the following. Note that the code for writing the image is not mine, but is taken from the accepted answer at Setting images to Clipboard - Java

    // Step 1 ) get old image
    BufferedImage img = null;
    try {
        img = (BufferedImage) Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.imageFlavor);
    } catch (UnsupportedFlavorException ufe) {
        ufe.printStackTrace();
    } catch (IOException ioe) {
        ioe.printStackTrace();
    }
    

    Taken from Setting images to Clipboard - Java :

    // Step 5 ) Reset clipboard
    ImageTransferable transferable = new ImageTransferable( image );
    Toolkit.getDefaultToolkit().getSystemClipboard().setContents(transferable, null);
    
    static class ImageTransferable implements Transferable
    {
        private Image image;
    
        public ImageTransferable (Image image)
        {
            this.image = image;
        }
    
        public Object getTransferData(DataFlavor flavor)
            throws UnsupportedFlavorException
        {
            if (isDataFlavorSupported(flavor))
            {
                return image;
            }
            else
            {
                throw new UnsupportedFlavorException(flavor);
            }
        }
    
        public boolean isDataFlavorSupported (DataFlavor flavor)
        {
            return flavor == DataFlavor.imageFlavor;
        }
    
        public DataFlavor[] getTransferDataFlavors ()
        {
            return new DataFlavor[] { DataFlavor.imageFlavor };
        }
    }
    

    这篇关于我自定义的“从剪贴板粘贴”行动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆