在鼠标坐标处的 textarea 上写入文本

Write text on textarea at mouse coordinates

我正在尝试创建类似于 MS paint 的东西,我需要一个可以单击场景并立即能够在我单击的位置进行书写的功能。我从这个 to solve how to switch between canvas and textarea. In other word how to switch between "drawing" and "writing" mode. So currently I can draw and write Current progress 中获取了整个代码示例,但我的问题是我想在我点击 textarea 的地方而不是在行的开头写文本。 这是我想象的样子(Goal)。

所以我想添加一个处理程序,它可以提供鼠标坐标并将插入符设置到该位置:

textarea.setOnMouseClicked(event->{
        textarea.positionCaret();
    });

才意识到positionCaret()只需要1个参数。 所以我无法将我的“插入符号”定位到鼠标单击的 x,y 位置。 所以问题是如何将“插入符”/光标移动到 textarea 中的任何给定位置?

解释插入符定位及其与您的目的无关的原因

您误解了 JavaFX 文本输入的插入符号位置相关 API 的概念。 APIs 与屏幕坐标无关。他们指的是插入符号相对于文本输入字段中文本的位置。

假设您有以下单词:

happy
  • 插入符位置 0 将插入符定位在 h.
  • 之前
  • 插入符位置 3 将插入符定位在两个 p 之间。

插入符号定位后。如果有人开始键入,新文本将插入到插入符号处。

所以如果你这样做:

setCaretPositon(3)

然后你输入haphap,然后文本会变成:

haphaphappy

如果有人在可编辑的文本字段中单击,JavaFX 系统足够智能,默认情况下可以处理单击,将插入符号放置在离单击最近的字母旁边(还可以处理选择和其他任务)。您无需编写任何代码即可获得该功能。

因此插入符号 API 与您要完成的任务无关。

文本(或任何其他节点)的绝对定位

如果您想在鼠标单击时为文本输入字段定义一个绝对位置,那么您可以使用与在 JavaFX 中定位任何节点完全相同的方式来执行此操作,即使用节点布局函数。具体来说,您设置节点的 x 和 y 坐标。坐标系及相关API在Node javadoc. To set both the x and y values at once, you call the relocate方法中有说明。

鼠标单击时在窗格中定位可编辑文本的示例

这里是一个例子,它生成一个新的文本区域,并将新文本区域的左上角定位在鼠标点击的位置。

Pane pane = new Pane();

pane.setOnMouseClicked(event -> {
    if (event.getTarget() == pane) {
        TextArea newTextArea = new TextArea();
        newTextArea.relocate(
                event.getX(), 
                event.getY()
        );
        pane.getChildren().add(
                newTextArea
        );
    }
});

该示例使用 Pane,因为它是一个父节点,不会将布局定位应用于其子节点(与 StackPane 不同,它会覆盖您设置的任何布局值并应用自己的布局算法,其中,默认情况下,会将节点置于其父节点的中心)。

您可以在以下问题的答案中看到更全面的示例:

  • How do I create an editable Label in javafx 2.2

该示例将在单击时在 Label 和 TextField 之间转换文本,以允许编辑标签值。您可以选择在您的绘图程序中使用此类功能,或者您可以按照 MS Paint 的方式进行操作。

如何模拟 MS 画图

MS Paint 所做的是允许您最初编辑文本,但是一旦您点击 return 提交编辑,它就会截取文本并将其绘制为 canvas 上的图像,将它从节点类型对象转换为 canvas 上的位。此后您不能再直接编辑文本。如果你想那样做,你可以使用节点 snapshot function and the graphics context drawImage function. If you do a snapshot, make sure you set the background correctly in the SnapshotParameters 的组合,这样它是透明的,这样文本背景就不会覆盖你的绘图(或者将背景设置为适当的颜色,如果你想要覆盖)。

此时我不会在此处提供此类功能的完整代码。

样式文本输入

您可能想要设置文本输入字段的样式(使用 CSS)以获得您想要的外观。可编辑标签示例提供了一些有关如何执行此操作的提示,但您可能希望为您的应用程序使用不同的样式。具体来说,文本输入的默认样式将有一个方框和背景,您可能想要也可能不想要。