package com.imyeyu.fx.ui.components; import com.imyeyu.fx.ui.TimiFXUI; import com.sun.javafx.scene.control.LabeledText; import javafx.beans.binding.Bindings; import javafx.beans.property.DoubleProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.collections.ListChangeListener; import javafx.scene.Node; import javafx.scene.control.Label; import javafx.scene.control.Skin; import javafx.scene.control.skin.LabelSkin; import javafx.scene.paint.Paint; import javafx.scene.shape.Rectangle; /** * 标题标签,此组件左侧显示标题,并添加中线分割,产生内容分割并充当标题。组件默认最大化宽度 * * @author 夜雨 * @since 2022-09-06 15:03 */ public class TitleLabel extends Label implements TimiFXUI { /** 标题与分割线间距 */ protected DoubleProperty spacing; /** 分割线颜色 */ protected ObjectProperty lineColor; /** 默认构造器 */ public TitleLabel() { this(""); } /** * 标准构造器 * * @param text 标题文本 */ public TitleLabel(String text) { super(text); lineColor = new SimpleObjectProperty<>(Colorful.BORDER); spacing = new SimpleDoubleProperty(6); setMaxWidth(Double.MAX_VALUE); } @Override protected Skin createDefaultSkin() { Skin defaultSkin = super.createDefaultSkin(); if (defaultSkin instanceof LabelSkin skin) { Rectangle line = new Rectangle(); line.setHeight(1); line.fillProperty().bind(lineColor); line.translateYProperty().bind(heightProperty().multiply(.5).subtract(1)); Node node = skin.getChildren().getFirst(); if (node instanceof LabeledText text) { line.widthProperty().bind(Bindings.createDoubleBinding(() -> { double textWidth = text.getLayoutBounds().getWidth(); return getWidth() - textWidth - spacing.get(); }, spacing, widthProperty(), text.layoutBoundsProperty())); line.translateXProperty().bind(Bindings.createDoubleBinding(() -> { double textWidth = text.getLayoutBounds().getWidth(); return textWidth + spacing.get(); }, spacing, text.layoutBoundsProperty())); } skin.getChildren().addListener((ListChangeListener) c -> { if (skin.getChildren().getFirst() != line) { skin.getChildren().addFirst(line); } }); skin.getChildren().addFirst(line); } return defaultSkin; } /** * 获取当前分割线颜色 * * @return 分割线颜色,默认 {@link TimiFXUI.Colorful#BORDER} */ public Paint getLineColor() { return lineColor.get(); } /** * 设置分割线颜色 * * @param lineColor 分割线颜色 */ public void setLineColor(Paint lineColor) { this.lineColor.set(lineColor); } /** * 获取分割线颜色监听 * * @return 分割线颜色监听 */ public ObjectProperty lineColorProperty() { return lineColor; } /** * 获取当前标题文本和分割线的间距 * * @return 标题文本和分割线的间距,默认 6 */ public double getSpacing() { return spacing.get(); } /** * 设置标题文本和分割线的间距 * * @param spacing 标题文本和分割线的间距 */ public void setSpacing(double spacing) { this.spacing.set(spacing); } /** * 获取当前标题文本和分割线的间距监听 * * @return 标题文本和分割线的间距监听 */ public DoubleProperty spacingProperty() { return spacing; } }