簡體   English   中英

JavaFX TextArea從坐標獲取插入位置

[英]JavaFX TextArea get caret position from coordinate

是否可以在JavaFX TextArea中的屏幕坐標(2個double int )處獲取插入位置( int )?

您可以在拖動處理程序中使用TextAreaSkin的getInsertionPoint方法:

TextAreaSkin skin = (TextAreaSkin) target.getSkin();
int insertionPoint = skin.getInsertionPoint(event.getX(),  event.getY());
target.positionCaret( insertionPoint);

但是,skin類在com.sun.javafx。*中,因此在Java 9出現時你可能不得不以不同的方式做事。 沒有人知道他們會破壞什么或他們提供什么作為替代品。 但是,使用Java 8它(現在)可以工作。

您可以將Label的文本拖動到TextArea中的任何位置的完整示例:

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
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;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

import com.sun.javafx.scene.control.skin.TextAreaSkin;

// Parts of this drag/drop example are from https://docs.oracle.com/javafx/2/drag_drop/HelloDragAndDrop.java.html
public class TextAreaDemo extends Application {

    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage primaryStage) {

        Label source = new Label( "Draggable Text");

        TextArea target = new TextArea();
        target.setPrefRowCount(10);
        target.setPrefColumnCount(100);
        target.setWrapText(true);
        target.setPrefWidth(150);

        String cssDefault = "Lorem ipsum dolor sit amet, et bonorum pertinacia est, verear temporibus definitionem nam an, ius cu justo legimus philosophia. Adversarium complectitur at sit, his ex sumo nibh consequuntur. Et vim adhuc mnesarchum, eum in ignota integre tincidunt. Erant oblique alterum no eos.";

        target.setText(cssDefault);

        HBox root = new HBox();
        root.setSpacing(10);
        HBox.setMargin(source, new Insets(10,10,10,10));
        HBox.setMargin(target, new Insets(10,10,10,10));
        root.getChildren().addAll( source, target);

        Scene scene = new Scene(root, 600, 330, Color.WHITE);
        primaryStage.setScene(scene);
        primaryStage.show();

        source.setOnDragDetected(new EventHandler <MouseEvent>() {
            public void handle(MouseEvent event) {

                /* 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) {

                /* 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);

                    // position caret at drag coordinates 
                    TextAreaSkin skin = (TextAreaSkin) target.getSkin();
                    int insertionPoint = skin.getInsertionPoint(event.getX(),  event.getY());
                    target.positionCaret( insertionPoint);

                }

                event.consume();
            }
        });

        target.setOnDragDropped(new EventHandler <DragEvent>() {
            public void handle(DragEvent event) {

                /* if there is a string data on dragboard, read it and use it */
                Dragboard db = event.getDragboard();
                boolean success = false;
                if (db.hasString()) {
                    target.insertText( target.getCaretPosition(), db.getString());
                    success = true;
                }
                /* let the source know whether the string was successfully 
                 * transferred and used */
                event.setDropCompleted(success);
                event.consume();
            }
        });
    }
}
import com.sun.javafx.scene.control.skin.TextAreaSkin;
import com.sun.javafx.scene.text.HitInfo;
/****************************************************/

TextAreaSkin skin = (TextAreaSkin) target.getSkin();
HitInfo mouseHit = skin.getIndex(e.getX(), e.getY());
// Now you can position caret
skin.positionCaret(mouseHit, false, false);
// And/or get insertion index
int insertionPoint = mouseHit.getInsertionIndex();

對於TextArea此方法等同於Roland的答案。 這種方法的實際區別在於它對TextFieldTextInputControl另一個子類)的適用性:

TextFieldSkin skin = (TextFieldSkin) target.getSkin();
HitInfo mouseHit = skin.getIndex(e.getX(), e.getY());
skin.positionCaret(mouseHit, false);
int insertionPoint = mouseHit.getInsertionIndex();

不幸的是, TextFieldSkin不會覆蓋getInsertionPoint(...) ,並且父實現返回0,因此替代解決方案在此處不起作用。

關於Java 9,Roland和我的答案仍然有效。 軟件包com.sun.javafx.scene.control.skincom.sun.javafx.scene.textHitInfo類所在的軟件包)正在轉移到Java 9中的公共API。它們的位置將是javafx.scene.control.skinjavafx.scene.text分別。 請參閱Javadocs for JavaFX 9: http//download.java.net/java/jdk9/jfxdocs/index.html

要始終查看光標,請將其放在setOnDragOver -Methode中

target.requestFocus();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM