java fx界面编辑_text – 如何在javafx 2.2中创建可编辑标签

本文展示了如何在JavaFX 2.2中创建可编辑的标签,这些标签可以拖动并放置在场景上。通过监听鼠标点击事件,动态添加可编辑的文本字段,并使用CSS进行样式设置,使其在未聚焦时看起来像普通标签。文章还讨论了调整文本字段大小的技巧,使用了私有API来获取字体测量信息。示例代码包括一个可拖动的可编辑文本类,当失去焦点且文本为空时会自动删除。
摘要由CSDN通过智能技术生成

我对如何实现这一点感到好奇,所以我试了一下.这就是我提出的.

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

I would start with a Pane, . . ., TextFields to represent text while being edited. Register mouse listeners with the Pane and Text objects, and use the layoutX and layoutY properties to position things . . . just to use text fields, and to use CSS to make them look like labels when not focused and text fields when focused.

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

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

TextCreator.java

// ## CAUTION: beware the com.sun imports...

import com.sun.javafx.tk.FontMetrics;

import com.sun.javafx.tk.Toolkit;

import javafx.application.Application;

import javafx.application.Platform;

import javafx.scene.Cursor;

import javafx.scene.Scene;

import javafx.scene.control.TextField;

import javafx.scene.image.Image;

import javafx.scene.image.ImageView;

import javafx.scene.layout.Pane;

import javafx.scene.layout.StackPane;

import javafx.stage.Stage;

/**

* Displays a map of the lonely mountain upon which draggable, editable labels can be overlaid.

*/

public class TextCreator extends Application {

private static final String MAP_IMAGE_LOC =

"http://images.wikia.com/lotr/images/archive/f/f6/20130209175313!F27c_thorins_map_from_the_hobbit.jpg";

public static void main(String[] args) throws Exception {

launch(args);

}

@Override

public void start(final Stage stage) throws Exception {

Pane pane = new Pane();

pane.setOnMouseClicked(event -> {

if (event.getTarget() == pane) {

pane.getChildren().add(

new EditableDraggableText(event.getX(), event.getY())

);

}

});

EditableDraggableText cssStyled =

new EditableDraggableText(439, 253, "Style them with CSS");

cssStyled.getStyleClass().add("highlighted");

pane.getChildren().addAll(

new EditableDraggableText(330, 101, "Click to add a label"),

new EditableDraggableText(318, 225, "You can edit your labels"),

cssStyled,

new EditableDraggableText(336, 307, "And drag them"),

new EditableDraggableText(309, 346, "Around The Lonely Mountain")

);

StackPane layout = new StackPane(

new ImageView(

new Image(

MAP_IMAGE_LOC

)

),

pane

);

Scene scene = new Scene(layout);

scene.getStylesheets().add(getClass().getResource(

"editable-text.css"

).toExternalForm());

stage.setScene(scene);

stage.setResizable(false);

stage.show();

}

/**

* A text field which has no special decorations like background, border or focus ring.

* i.e. the EditableText just looks like a vanilla Text node or a Label node.

*/

class EditableText extends TextField {

// The right margin allows a little bit of space

// to the right of the text for the editor caret.

private final double RIGHT_MARGIN = 5;

EditableText(double x, double y) {

relocate(x, y);

getStyleClass().add("editable-text");

//** CAUTION: this uses a non-public API (FontMetrics) to calculate the field size

// the non-public API may be removed in a future JavaFX version.

// see: https://javafx-jira.kenai.com/browse/RT-8060

// Need font/text measurement API

FontMetrics metrics = Toolkit.getToolkit().getFontLoader().getFontMetrics(getFont());

setPrefWidth(RIGHT_MARGIN);

textProperty().addListener((observable, oldTextString, newTextString) ->

setPrefWidth(metrics.computeStringWidth(newTextString) + RIGHT_MARGIN)

);

Platform.runLater(this::requestFocus);

}

}

/**

* An EditableText (a text field which looks like a label), which can be dragged around

* the screen to reposition it.

*/

class EditableDraggableText extends StackPane {

private final double PADDING = 5;

private EditableText text = new EditableText(PADDING, PADDING);

EditableDraggableText(double x, double y) {

relocate(x - PADDING, y - PADDING);

getChildren().add(text);

getStyleClass().add("editable-draggable-text");

// if the text is empty when we lose focus,

// the node has no purpose anymore

// just remove it from the scene.

text.focusedProperty().addListener((observable, hadFocus, hasFocus) -> {

if (!hasFocus && getParent() != null && getParent() instanceof Pane &&

(text.getText() == null || text.getText().trim().isEmpty())) {

((Pane) getParent()).getChildren().remove(this);

}

});

enableDrag();

}

public EditableDraggableText(int x, int y, String text) {

this(x, y);

this.text.setText(text);

}

// make a node movable by dragging it around with the mouse.

private void enableDrag() {

final Delta dragDelta = new Delta();

setOnMousePressed(mouseEvent -> {

this.toFront();

// record a delta distance for the drag and drop operation.

dragDelta.x = mouseEvent.getX();

dragDelta.y = mouseEvent.getY();

getScene().setCursor(Cursor.MOVE);

});

setOnMouseReleased(mouseEvent -> getScene().setCursor(Cursor.HAND));

setOnMouseDragged(mouseEvent -> {

double newX = getLayoutX() + mouseEvent.getX() - dragDelta.x;

if (newX > 0 && newX < getScene().getWidth()) {

setLayoutX(newX);

}

double newY = getLayoutY() + mouseEvent.getY() - dragDelta.y;

if (newY > 0 && newY < getScene().getHeight()) {

setLayoutY(newY);

}

});

setOnMouseEntered(mouseEvent -> {

if (!mouseEvent.isPrimaryButtonDown()) {

getScene().setCursor(Cursor.HAND);

}

});

setOnMouseExited(mouseEvent -> {

if (!mouseEvent.isPrimaryButtonDown()) {

getScene().setCursor(Cursor.DEFAULT);

}

});

}

// records relative x and y co-ordinates.

private class Delta {

double x, y;

}

}

}

编辑-text.css

.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;

}

如果您有时间,可以清理样本实施并将其捐赠给ControlsFX项目.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值