[英]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的答案。 這種方法的實際區別在於它對TextField
( TextInputControl
另一個子類)的適用性:
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.skin
和com.sun.javafx.scene.text
( HitInfo
類所在的軟件包)正在轉移到Java 9中的公共API。它們的位置將是javafx.scene.control.skin
和javafx.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.