How can I copy a file from the compose app into a ...
# compose-desktop
n
How can I copy a file from the compose app into a OS clipboard? I tried the code below, but it somehow copies the file into my apps clipboard, or JVMs clipboard if it makes sense. When I try to paste the file into other OS app it simply does not work, while the copied file works for my app. Note that when I copy a String into OS clipboard from my compose app - other apps can see it.
Copy code
val clipboard = Toolkit.getDefaultToolkit().systemClipboard

val fileList = listOf(file.value)
val transferable = object : Transferable {
    override fun getTransferData(flavor: DataFlavor) =
        if (flavor == DataFlavor.javaFileListFlavor) fileList else throw UnsupportedOperationException()
    override fun isDataFlavorSupported(flavor: DataFlavor) = flavor == DataFlavor.javaFileListFlavor
    override fun getTransferDataFlavors() = arrayOf(DataFlavor.javaFileListFlavor)
}
clipboard.setContents(transferable, null)
a
It’s a question about AWT, really, not Compose. At first glance it seems like it should work, though.
d
Might be worth trying it the other way around in a sandbox app, and logging what the flavor actually is. So, copy out of finder/explorer into your app, and see what the dataflavor actually is.
I asked Copilot to create such a debugger for me, and it delivered. Better than I expected actually.
t
I do have working code to export an image to the clipboard. Not sure but if you are interested i can show it here:
n
That would help! Does it also work for arbitrary files?
t
It is just for images. But maybe if you do some research you can modify it to work for files. But i do not know.
Copy code
object ClipboardImage {
    /**
     * Place an image on the system clipboard.
     *
     * @param  image - the image to be added to the system clipboard
     */
    fun write(image: ImageBitmap) {
        val transferable = ImageTransferable(image.toAwtImage())
        Toolkit.getDefaultToolkit().systemClipboard.setContents(transferable, null)
    }

    internal class ImageTransferable(private val image: Image) : Transferable {
        @Throws(UnsupportedFlavorException::class)
        override fun getTransferData(flavor: DataFlavor): Any {
            if (isDataFlavorSupported(flavor)) {
                return image
            } else {
                throw UnsupportedFlavorException(flavor)
            }
        }
        override fun isDataFlavorSupported(flavor: DataFlavor) = flavor === DataFlavor.imageFlavor
        override fun getTransferDataFlavors() = arrayOf(DataFlavor.imageFlavor)
    }
}