Я столкнулся с несколькими проблемами, пытаясь реализовать это простым способом. Мне пришлось создать переключатель, который позволил бы мне выбрать текст, а затем перетащить текст. Во время перетаскивания я заметил, что он не будет захватывать весь выделенный текст, если перетаскивание не было начато в конце выделенного текста. Я исправил это, захватив выделенный текст после того, как он был выбран, и режим переключения переключается в режим перетаскивания. MCVE ниже.
Главная * * 1004
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.Parent;
public class Main extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("Test.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setTitle("Simple Drag and Drop ExampleGame");
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.ToggleButton?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane id="AnchorPane" prefHeight="583.0" prefWidth="851.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javaapplication12.TestController">
<children>
<ListView fx:id="listView" layoutX="326.0" layoutY="14.0" onDragDropped="#dragDropped" onDragEntered="#dragEntered" onDragOver="#dragOver" prefHeight="200.0" prefWidth="200.0" />
<TextArea fx:id="textArea" layoutX="224.0" layoutY="274.0" onDragDetected="#dragDetected" prefHeight="247.0" prefWidth="426.0" text="There was once a velveteen rabbit, and in the beginning he was really splendid. He was fat and bunchy, as a rabbit should be; his coat was spotted brown and white, he had real thread whiskers, and his ears were lined with pink sateen. On Christmas morning, when he sat wedged in the top of the Boy’s stocking, with a sprig of holly between his paws, the effect was charming." wrapText="true" />
<ToggleButton fx:id="tbtnDragMode" layoutX="44.0" layoutY="26.0" mnemonicParsing="false" onAction="#handleTbtnDragMode" text="Select Text Mode" />
</children>
</AnchorPane>
Контроллер
import java.net.URL;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ListView;
import javafx.scene.control.TextArea;
import javafx.scene.control.ToggleButton;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
public class TestController implements Initializable {
@FXML TextArea textArea;
@FXML ListView listView;
@FXML ToggleButton tbtnDragMode;
ObservableList<String> list = FXCollections.observableArrayList();
String selectedText = "";
@Override
public void initialize(URL url, ResourceBundle rb) {
listView.setItems(list);
list.add("test");
}
@FXML private void handleTbtnDragMode(ActionEvent actionEvent)
{
if(tbtnDragMode.isSelected())
{
System.out.println("Drag Mode On");
tbtnDragMode.setText("Drag Mode");
selectedText = textArea.getSelectedText().isBlank() ? "" : textArea.getSelectedText();
}
else {
System.out.println("Drag Mode Off");
tbtnDragMode.setText("Select Text Mode");
}
}
@FXML
private void dragDetected(MouseEvent event) {
System.out.println("drag detected 1");
System.out.println(tbtnDragMode.isSelected());
if(tbtnDragMode.isSelected())
{
System.out.println("drag detected 2");
/* drag was detected, start a drag-and-drop gesture*/
/* allow any transfer mode */
Dragboard db = textArea.startDragAndDrop(TransferMode.ANY);
/* Put a string on a dragboard */
ClipboardContent content = new ClipboardContent();
content.putString(selectedText);
db.setContent(content);
event.consume();
}
}
@FXML
private void dragEntered(DragEvent event) {
System.out.println("dragEntered");
event.consume();
}
@FXML
private void dragDropped(DragEvent event)
{
System.out.println("Drag dropped");
/* data dropped */
/* if there is a string data on dragboard, read it and use it */
Dragboard db = event.getDragboard();
boolean success = false;
if (db.hasString()) {
list.add(db.getString());
success = true;
}
/* let the source know whether the string was successfully
* transferred and used */
event.setDropCompleted(success);
event.consume();
}
@FXML
private void dragDone(DragEvent event) {
/* the drag and drop gesture ended */
/* if the data was successfully moved, clear it */
System.out.println("drag done");
if (event.getTransferMode() == TransferMode.MOVE) {
//clear textarea selection
System.out.println("drag done");
}
event.consume();
}
@FXML
private void dragExited(DragEvent event) {
System.out.println("dragExited");
event.consume();
}
@FXML
private void dragOver(DragEvent event) {
/* data is dragged over the target */
/* accept it only if it is not dragged from the same node
* and if it has a string data */
System.out.println(event.getGestureSource() + " - " + event.getTarget());
if (event.getGestureSource() != event.getTarget() &&
event.getDragboard().hasString()) {
/* allow for both copying and moving, whatever user chooses */
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
}
event.consume();
}
}