Установка изображений в буфер обмена — Java

#java #clipboard

#java #буфер обмена

Вопрос:

Я создаю программу с использованием Java, которая отправляет содержимое буфера обмена через сокеты; Мне удалось заставить его работать со строками, но у меня возникли некоторые проблемы с изображениями. Вот код:

     //get Image
    Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
    Image imageContents = (Image)clipboard.getData(DataFlavor.imageFlavor);
    ImageIcon image = new ImageIcon(imageContents);

    //sent over sockets

    //set Image
    String mime = DataFlavor.imageFlavor.getMimeType();
    DataHandler contents = new DataHandler(image,mime);

    //set clipboard
    clipboard.setContents(contents, null);
  

После setContents буфер обмена пуст; Есть идеи, почему и как это исправить?

Ответ №1:

Вот некоторый код, который я использовал для записи / чтения изображения из буфера обмена. Никогда не пробовал это с сокетами, поэтому я не уверен, что это поможет:

 import java.awt.*;
import java.awt.datatransfer.*;

public class ClipboardImage
{
    /**
     *  Retrieve an image from the system clipboard.
     *
     *  @return the image from the clipboard or null if no image is found
     */
    public static Image read()
    {
        Transferable t = Toolkit.getDefaultToolkit().getSystemClipboard().getContents( null );

        try
        {
            if (t != null amp;amp; t.isDataFlavorSupported(DataFlavor.imageFlavor))
            {
                Image image = (Image)t.getTransferData(DataFlavor.imageFlavor);
                return image;
            }
        }
        catch (Exception e) {}

        return null;
    }

    /**
     *  Place an image on the system clipboard.
     *
     *  @param  image - the image to be added to the system clipboard
     */
    public static void write(Image image)
    {
        if (image == null)
            throw new IllegalArgumentException ("Image can't be null");

        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 };
        }
    }

    public static void main(String[] args)
    {
        Image image = Toolkit.getDefaultToolkit ().createImage("???.jpg");
        ClipboardImage.write( image );

        javax.swing.ImageIcon icon = new javax.swing.ImageIcon( ClipboardImage.read() );
        javax.swing.JLabel label = new javax.swing.JLabel( icon );

        javax.swing.JFrame frame = new javax.swing.JFrame();
        frame.setDefaultCloseOperation( javax.swing.JFrame.EXIT_ON_CLOSE );
        frame.getContentPane().add( label );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
    }
}
  

Ответ №2:

DataHandler не будет функционировать так, как вы предписали, потому что в соответствии с API:

DataHandler реализует переносимый интерфейс, чтобы данные можно было использовать в операциях передачи данных AWT, таких как вырезание и вставка, перетаскивание. Реализация переносимого интерфейса зависит от доступности установленного объекта DataContentHandler, соответствующего типу MIME данных, представленных в конкретном экземпляре DataHandler.

Я понимаю, что это означает, что, если вы не используете его setDataContentHandlerFactory метод и не реализуете в нем все необходимые интерфейсы, по сути, DataHandler просто вернет null . Вероятно, это причина, по которой DataHandler работает не так, как вы ожидаете. Несмотря на то, что он реализует Transferable интерфейс, он не реализует его таким образом, чтобы он функционировал адекватно вашим конкретным потребностям.
Эта функциональность будет предоставляться a DataContentHandler , реализация которого будет оставлена на ваше усмотрение.

Кажется менее утомительным напрямую реализовывать переносимый класс, как предлагалось ранее.