Files
timi-fx-ui/src/main/java/com/imyeyu/fx/ui/components/SelectableLabel.java
2026-05-11 21:38:37 +08:00

173 lines
4.4 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.imyeyu.fx.ui.components;
import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.java.ref.Ref;
import com.sun.javafx.scene.control.skin.Utils;
import javafx.application.Platform;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.ListChangeListener;
import javafx.scene.Cursor;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.Skin;
import javafx.scene.control.TextArea;
import javafx.scene.control.skin.TextAreaSkin;
import javafx.scene.layout.Region;
import javafx.scene.paint.Paint;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import java.util.List;
/**
* 可选中的标签组件,实际上是无样式文本域,此组件适应布局最大宽度
*
* @author 夜雨
* @since 2022-01-29 01:24
*/
public class SelectableLabel extends TextArea implements TimiFXUI, TimiFXUI.Colorful {
private static final String STYLE_CLASS = "selectable-label";
private final ObjectProperty<Paint> textFillProperty;
private final ObjectProperty<TextAlignment> textAlignmentProperty;
/** 默认构造 */
public SelectableLabel() {
this("");
}
/**
* 构造器
*
* @param text 文本内容
*/
public SelectableLabel(String text) {
super(text);
textFillProperty = new SimpleObjectProperty<>(BLACK);
textAlignmentProperty = new SimpleObjectProperty<>(TextAlignment.LEFT);
setCursor(Cursor.TEXT);
setEditable(false);
setWrapText(true);
setMaxWidth(Double.MAX_VALUE);
setMinSize(Double.MIN_VALUE, Double.MIN_VALUE);
setPrefHeight(0);
setPrefSize(0, 0);
getStyleClass().setAll(STYLE_CLASS, CSS.MINECRAFT);
focusedProperty().addListener((obs, o, isFocused) -> {
if (!isFocused) {
deselect();
}
});
}
@Override
protected Skin<?> createDefaultSkin() {
Skin<?> defaultSkin = super.createDefaultSkin();
if (defaultSkin instanceof TextAreaSkin skin) {
try {
ScrollPane sp = Ref.getFieldValue(skin, "scrollPane", ScrollPane.class);
sp.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
if (sp.getContent() instanceof Region region) {
region.heightProperty().addListener((obs, o, newHeight) -> Platform.runLater(() -> {
// 需要 runLater因为是 Region 适应 Skin 变化
setPrefHeight(newHeight.doubleValue());
}));
}
Group paragraphNodes = Ref.getFieldValue(skin, "paragraphNodes", Group.class);
paragraphNodes.getChildren().addListener((ListChangeListener<Node>) c -> {
if (c.next()) {
if (c.wasAdded()) {
bindTextStyle(c.getAddedSubList());
}
}
});
bindTextStyle(paragraphNodes.getChildren());
widthProperty().addListener((obs, oldValue, newValue) -> {
if (oldValue.doubleValue() < newValue.doubleValue()) {
if (paragraphNodes.getChildren().getFirst() instanceof Text text) {
setPrefHeight(Utils.computeTextHeight(getFont(), getText(), getWidth(), text.getBoundsType()));
}
}
});
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
return defaultSkin;
}
/**
* 绑定文本样式
*
* @param list 文本节点,必须是 {@link Text}
*/
private void bindTextStyle(List<? extends Node> list) {
for (Node node : list) {
if (node instanceof Text text) {
text.fillProperty().bind(textFillProperty);
text.textAlignmentProperty().bind(textAlignmentProperty);
}
}
}
/**
* 设置字体颜色
*
* @param textFill 字体颜色
*/
public void setTextFill(Paint textFill) {
this.textFillProperty.set(textFill);
}
/**
* 获取字体颜色
*
* @return 字体颜色
*/
public Paint getTextFill() {
return textFillProperty.get();
}
/**
* 获取字体颜色绑定
*
* @return 字体颜色绑定
*/
public ObjectProperty<Paint> textFillProperty() {
return textFillProperty;
}
/**
* 设置文本对齐方式
*
* @param textAlignment 文本对齐方式
*/
public void setTextAlignment(TextAlignment textAlignment) {
this.textAlignmentProperty.set(textAlignment);
}
/**
* 获取文本对齐方式
*
* @return 文本对齐方式
*/
public TextAlignment getTextAlignment() {
return textAlignmentProperty.get();
}
/**
* 获取文本对齐方式绑定
*
* @return 文本对齐方式绑定
*/
public ObjectProperty<TextAlignment> textAlignmentProperty() {
return textAlignmentProperty;
}
}