Copying files does not work:
def toClipboard(selectedLinesOnly: Boolean = false): Unit = {
val clipboard = Clipboard.systemClipboard
val content = new ClipboardContent
val items: Iterable[FileRecord] = selectedLinesOnly match {
case true => tableView.selectionModel.value.selectedItems.toSeq
case false => tableView.items.value
}
val files = items.map(_.file)
println(s"COPY $files")
content.putFiles(files.toSeq)
clipboard.content = content
}
Output: [info] COPY [SFX][/tmp/test/a.txt, /tmp/test/b.txt]
No files to paste.
def toClipboard(selectedLinesOnly: Boolean = false): Unit = {
val clipboard = Clipboard.systemClipboard
val content = new ClipboardContent
val items: Iterable[FileRecord] = selectedLinesOnly match {
case true => tableView.selectionModel.value.selectedItems.toSeq
case false => tableView.items.value
}
val files = items.map(_.file.getPath)
println(s"COPY $files")
content.putFilesByPath(files.toSeq)
clipboard.content = content
}
Output: [info] COPY [SFX][/tmp/test/a.txt, /tmp/test/b.txt]
No files to paste.
def toClipboard(selectedLinesOnly: Boolean = false): Unit = {
val clipboard = Clipboard.systemClipboard
val content = new ClipboardContent
val items: Iterable[FileRecord] = selectedLinesOnly match {
case true => tableView.selectionModel.value.selectedItems.toSeq
case false => tableView.items.value
}
val files = items.map("file://" + _.file.getPath)
println(s"COPY $files")
content.putFilesByPath(files.toSeq)
clipboard.content = content
}
Output: [info] COPY [SFX][file:///tmp/test/a.txt, file:///tmp/test/b.txt]
No files to paste.
But copying the paths to the string clipboard is possible:
def toClipboard(selectedLinesOnly: Boolean = false): Unit = {
val clipboard = Clipboard.systemClipboard
val content = new ClipboardContent
val items: Iterable[FileRecord] = selectedLinesOnly match {
case true => tableView.selectionModel.value.selectedItems.toSeq
case false => tableView.items.value
}
val files = items.map(_.file.getPath)
println(s"COPY $files")
content.putString(files.mkString(" "))
clipboard.content = content
}
Now this is in my clipboard: "/tmp/test/a.txt /tmp/test/b.txt"
But I need it in the form of files, not a string.
How can I make copying files work in my application?
I am working with OpenJFX 8 on Ubuntu.
ClipBoard
doesn't have the functionality like FileUtils.copyDirectoryToDirectory
and FileUtils.moveDirectoryToDirectory
(aka copy or cut). Clipboard can give only path or general data. This features can be possible using Drag and Drop by Dragboard
.
During the drag-and-drop gesture, various types of data can be transferred such as
text, images, URLs, files, bytes, and strings
.The
javafx.scene.input.DragEvent
class is the basic class used to implement the drag-and-drop gesture. For more information on particular methods and other classes in thejavafx.scene.input
package, see the API documentation.
For more, you can go through this tutorial: Drag-and-Drop Feature in JavaFX Applications
package hellodraganddrop;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.*;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Stage;
/**
* Demonstrates a drag-and-drop feature.
*/
public class HelloDragAndDrop extends Application {
@Override public void start(Stage stage) {
stage.setTitle("Hello Drag And Drop");
Group root = new Group();
Scene scene = new Scene(root, 400, 200);
scene.setFill(Color.LIGHTGREEN);
final Text source = new Text(50, 100, "DRAG ME");
source.setScaleX(2.0);
source.setScaleY(2.0);
final Text target = new Text(250, 100, "DROP HERE");
target.setScaleX(2.0);
target.setScaleY(2.0);
source.setOnDragDetected(new EventHandler <MouseEvent>() {
public void handle(MouseEvent event) {
/* drag was detected, start drag-and-drop gesture*/
System.out.println("onDragDetected");
/* allow any transfer mode */
Dragboard db = source.startDragAndDrop(TransferMode.ANY);
/* put a string on dragboard */
ClipboardContent content = new ClipboardContent();
content.putString(source.getText());
db.setContent(content);
event.consume();
}
});
target.setOnDragOver(new EventHandler <DragEvent>() {
public void handle(DragEvent event) {
/* data is dragged over the target */
System.out.println("onDragOver");
/* accept it only if it is not dragged from the same node
* and if it has a string data */
if (event.getGestureSource() != target &&
event.getDragboard().hasString()) {
/* allow for both copying and moving, whatever user chooses */
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
}
event.consume();
}
});
target.setOnDragEntered(new EventHandler <DragEvent>() {
public void handle(DragEvent event) {
/* the drag-and-drop gesture entered the target */
System.out.println("onDragEntered");
/* show to the user that it is an actual gesture target */
if (event.getGestureSource() != target &&
event.getDragboard().hasString()) {
target.setFill(Color.GREEN);
}
event.consume();
}
});
target.setOnDragExited(new EventHandler <DragEvent>() {
public void handle(DragEvent event) {
/* mouse moved away, remove the graphical cues */
target.setFill(Color.BLACK);
event.consume();
}
});
target.setOnDragDropped(new EventHandler <DragEvent>() {
public void handle(DragEvent event) {
/* data dropped */
System.out.println("onDragDropped");
/* if there is a string data on dragboard, read it and use it */
Dragboard db = event.getDragboard();
boolean success = false;
if (db.hasString()) {
target.setText(db.getString());
success = true;
}
/* let the source know whether the string was successfully
* transferred and used */
event.setDropCompleted(success);
event.consume();
}
});
source.setOnDragDone(new EventHandler <DragEvent>() {
public void handle(DragEvent event) {
/* the drag-and-drop gesture ended */
System.out.println("onDragDone");
/* if the data was successfully moved, clear it */
if (event.getTransferMode() == TransferMode.MOVE) {
source.setText("");
}
event.consume();
}
});
root.getChildren().add(source);
root.getChildren().add(target);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
Actually Java have some ways to copy file: 4 Ways to Copy File in Java
My solution which I tested successfully with Ubuntu:
FilesTransferable.scala
package myapp.clipboard
import java.awt.datatransfer._
case class FilesTransferable(files: Iterable[String]) extends Transferable {
val clipboardString: String = "copy\n" + files.map(path => s"file://$path").mkString("\n")
val dataFlavor = new DataFlavor("x-special/gnome-copied-files")
def getTransferDataFlavors(): Array[DataFlavor] = {
Seq(dataFlavor).toArray
}
def isDataFlavorSupported(flavor: DataFlavor): Boolean = {
dataFlavor.equals(flavor)
}
@throws(classOf[UnsupportedFlavorException])
@throws(classOf[java.io.IOException])
def getTransferData(flavor: DataFlavor): Object = {
if(flavor.getRepresentationClass() == classOf[java.io.InputStream]) {
new java.io.ByteArrayInputStream(clipboardString.getBytes())
} else {
return null;
}
}
}
Clipboard.scala
package myapp.clipboard
import java.awt.Toolkit
import java.awt.datatransfer._
object Clipboard {
def toClipboard(
transferable: Transferable,
lostOwnershipCallback: (Clipboard, Transferable) => Unit =
{ (clipboard: Clipboard, contents: Transferable) => Unit }
): Unit = {
Toolkit.getDefaultToolkit.getSystemClipboard.setContents(
transferable,
new ClipboardOwner {
def lostOwnership(clipboard: Clipboard, contents: Transferable): Unit = {
lostOwnershipCallback(clipboard, contents)
}
}
)
}
}
Quite a lot code for such a basic functionality (and still not OS independent).
Usage Example:
val transferable = FilesTransferable(filePaths)
myapp.clipboard.Clipboard.toClipboard(transferable, { (cb, contents) =>
println(s"lost clipboard ownership (clipboard: $cb)")
})
If it is true that there still do not exist any solutions which are part of Java-AWT/Swing/JavaFX/Scala-Swing/ScalaFX (actually, I still can't believe it), my plan is to build an easy-to-use clipboard library which supports at least OS X, Ubuntu and Windows.
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.