Text 如何在JavaFX2.2中创建可编辑标签

Text 如何在JavaFX2.2中创建可编辑标签,text,javafx,controls,Text,Javafx,Controls,我希望在我正在书写的窗格上的任意位置创建一个可编辑标签。我的印象是,TextField或TextArea对象是我可以用来实现该功能的对象。显然还有更多的问题,因为我不知道在创建对象时如何定位它。我在“混乱的Java”网站上找到了一个例子,但我需要做更多的工作来了解那里发生了什么 我正在从这个小组寻求更多的投入 (没有错误,因为我没有编写任何代码。)我有点好奇如何实现这一点,所以我尝试了一下。这就是我想到的 使用的方法与James在评论中提出的方法非常相同: 我会从一个窗格开始。,文本字段,用于

我希望在我正在书写的窗格上的任意位置创建一个可编辑标签。我的印象是,TextField或TextArea对象是我可以用来实现该功能的对象。显然还有更多的问题,因为我不知道在创建对象时如何定位它。我在“混乱的Java”网站上找到了一个例子,但我需要做更多的工作来了解那里发生了什么

我正在从这个小组寻求更多的投入


(没有错误,因为我没有编写任何代码。)

我有点好奇如何实现这一点,所以我尝试了一下。这就是我想到的

使用的方法与James在评论中提出的方法非常相同:

我会从一个窗格开始。,文本字段,用于在编辑时表示文本。向窗格和文本对象注册鼠标侦听器,并使用layoutX和layoutY属性定位对象。只需使用文本字段,并使用CSS使它们在未聚焦时看起来像标签,在聚焦时像文本字段

唯一非常棘手的部分是如何正确调整文本字段的大小,因为文本字段中的文本不会通过公共API公开,从而允许您监听其布局边界。您也许可以使用css查找函数来获取包含的文本,但我选择使用私有的sun FontMetrics API(将来可能会被弃用)来获取文本的大小。将来使用Java9时,您应该能够在不使用私有API的情况下执行任务

该解决方案不尝试做任何棘手的事情,比如处理多格式或多行文本,它只是简单的,可以放置在场景上的几句话的单行注释

TextCreator.java


如果有时间,您可以清理示例实现并将其捐赠给项目。

您可以使用label:
setGraphic()
函数

这是我的密码:

public void editableLabelTest(Stage stage){
    Scene scene = new Scene(new VBox(new EditableLabel("I am a label"),
                                    new EditableLabel("I am a label too")));
    stage.setScene(scene);
    stage.show();
}

class EditableLabel extends Label{
    TextField tf = new TextField();
    /***
     * backup is used to cancel when press ESC...
     */
    String backup = "";
    public EditableLabel(){
        this("");
    }
    public EditableLabel(String str){
        super(str);
        this.setOnMouseClicked(e -> {
            if(e.getClickCount() == 2){
                tf.setText(backup = this.getText());
                this.setGraphic(tf);
                this.setText("");
                tf.requestFocus();
            }
        });
        tf.focusedProperty().addListener((prop, o, n) -> {
            if(!n){
                toLabel();
            }
        });
        tf.setOnKeyReleased(e -> {
            if(e.getCode().equals(KeyCode.ENTER)){
                toLabel();
            }else if(e.getCode().equals(KeyCode.ESCAPE)){
                tf.setText(backup);
                toLabel();
            }
        });
    }

    void toLabel(){
        this.setGraphic(null);
        this.setText(tf.getText());
    }

}

根是什么?锚烷?窗玻璃你的问题现在太宽泛了。更改它并添加一个复制错误的标签。我不清楚“可编辑标签”与
TextField
有何不同。为什么不直接使用
TextField
?想象一下,只需在您正在工作的窗口中的任意位置键入文本,而不必将其与任何其他控件关联。稍后我可能想编辑该文本,所以我点击文本,瞧!文本变得可编辑。嗯,这相当复杂,因此本身不是一个代码服务,所以你必须尝试一些东西,如果你的代码表现不符合预期,你可以使用这些论坛寻求帮助。我将从一个
窗格开始,使用
文本
对象表示静态文本,使用
文本字段
表示正在编辑的文本。使用
窗格
文本
对象注册鼠标侦听器,并使用
layoutX
layoutY
属性定位对象。另一种方法可能只是使用文本字段,并使用CSS使它们在未聚焦时看起来像标签,在聚焦时像文本字段。非常好,+1!如果有人愿意/不愿意改进,请让我知道。在这方面进行部分/全部工作将是非常好的;)我编辑了css文件以使用/**/comments。直到我在粘贴文件内容时意识到css文件被IDEA弄坏了,手动光标和拖动才起作用。JavaFX在解析css文件时没有抱怨。manglement如下所示:``-fx背景色:rgba(255、182、93、0.3);//半透明薄纱-fx边框样式:虚线```理想情况下,TextField文本的位置应与标签文本相同,TextArea的大小应与标签完全相同。我翻了很多遍,不知道怎么做。我认为
setonkeyreased
应该是
setonkeyressed
。即使您使用enter事件,例如,当使用
setOnKeyReleased
时,它也可能会传递给默认按钮。
.editable-text {
    -fx-background-color: transparent;
    -fx-background-insets: 0;
    -fx-background-radius: 0;
    -fx-padding: 0;
}

.editable-draggable-text:hover .editable-text {
    -fx-background-color: yellow;
}

.editable-draggable-text {
    -fx-padding: 5;
    -fx-background-color: rgba(152, 251, 152, 0.2); // translucent palegreen
}

.editable-draggable-text:hover {
    -fx-background-color: orange;
}

.highlighted {
    -fx-background-color: rgba(255, 182, 93, 0.3);  // translucent mistyrose
    -fx-border-style: dashed;
    -fx-border-color: firebrick;
}
public void editableLabelTest(Stage stage){
    Scene scene = new Scene(new VBox(new EditableLabel("I am a label"),
                                    new EditableLabel("I am a label too")));
    stage.setScene(scene);
    stage.show();
}

class EditableLabel extends Label{
    TextField tf = new TextField();
    /***
     * backup is used to cancel when press ESC...
     */
    String backup = "";
    public EditableLabel(){
        this("");
    }
    public EditableLabel(String str){
        super(str);
        this.setOnMouseClicked(e -> {
            if(e.getClickCount() == 2){
                tf.setText(backup = this.getText());
                this.setGraphic(tf);
                this.setText("");
                tf.requestFocus();
            }
        });
        tf.focusedProperty().addListener((prop, o, n) -> {
            if(!n){
                toLabel();
            }
        });
        tf.setOnKeyReleased(e -> {
            if(e.getCode().equals(KeyCode.ENTER)){
                toLabel();
            }else if(e.getCode().equals(KeyCode.ESCAPE)){
                tf.setText(backup);
                toLabel();
            }
        });
    }

    void toLabel(){
        this.setGraphic(null);
        this.setText(tf.getText());
    }

}