Javafx Проблема при перетаскивании выделенного текста из TextArea - PullRequest
0 голосов
/ 06 июня 2019

У меня странная проблема при перетаскивании выделенного текста из TextArea. Текст выбран правильно, но когда я перетаскиваю его, чтобы поместить на целевую позицию, выбор текста изменяется, это уменьшает выбор случайным образом на 2-3 символа.

Вот полный класс:

public class DnDMainController extends Application {


    ClipboardContent cb = new ClipboardContent();
    ObservableList<String> list = FXCollections.observableArrayList();
    @FXML
    private TextArea sourceText;
    @FXML
    private ListView<String> listView;
    @Override
    public void start(Stage stage) throws Exception {

        Parent root = FXMLLoader.load(getClass().getResource("/main/DnD.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
    void _detectDrag(MouseEvent event) {
        Dragboard db = sourceText.startDragAndDrop(TransferMode.COPY);
        cb.putString(sourceText.getSelectedText());
        db.setContent(cb);
        event.consume();
    }

    @FXML
    void _dragExited(DragEvent event) {
        String st = event.getDragboard().getString();
        if (!(list.contains(st.trim()))) {
        list.add(st);
        listView.getItems().addAll(list);
    }}

}

[![gif for DnD Issue][1]][1]

Я пробовал то же самое на TextField, и он отлично работает на TextField. Но, к сожалению, я не могу использовать TextField из-за большой строки текста. Я не знаю, что я делаю неправильно ...

enter image description here

FXML-код:


<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="549.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="main.DnDMainController">
   <children>
      <TextArea fx:id="sourceText" layoutY="273.0" onDragDetected="#_detectDrag" prefHeight="127.0" prefWidth="550.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">
         <font>
            <Font size="19.0" />
         </font></TextArea>
      <ListView fx:id="listView" layoutY="40.0" onDragExited="#_dragExited" onMouseClicked="#_callContext" prefHeight="200.0" prefWidth="516.0" />
      <Label alignment="CENTER" contentDisplay="CENTER" layoutX="-2.0" layoutY="2.0" prefHeight="38.0" prefWidth="550.0" text="List of Words" textAlignment="CENTER" />
      <Label alignment="CENTER" contentDisplay="CENTER" layoutX="7.0" layoutY="240.0" prefHeight="32.0" prefWidth="542.0" text="Story" textAlignment="CENTER" />
   </children>
</AnchorPane>```

1 Ответ

0 голосов
/ 06 июня 2019

Я столкнулся с несколькими проблемами, пытаясь реализовать это простым способом. Мне пришлось создать переключатель, который позволил бы мне выбрать текст, а затем перетащить текст. Во время перетаскивания я заметил, что он не будет захватывать весь выделенный текст, если перетаскивание не было начато в конце выделенного текста. Я исправил это, захватив выделенный текст после того, как он был выбран, и режим переключения переключается в режим перетаскивания. 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();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...