添加标签行javafx

时间:2018-07-18 14:30:47

标签: javafx javafx-2 javafx-3d

我希望在Javafx中添加比例尺文本并在行的角落添加箭头。
谢谢。

enter image description here

1 个答案:

答案 0 :(得分:0)

我建议扩展Region以使元素保持在一起并布置子元素。

ScaleView

这更易于实现。我建议使用Path而不是单独的行,因为这样可以简化尺寸设置。

public class ScaleView extends Region {

    private final Label text;
    private final Path path;
    private final VLineTo down;
    private final HLineTo right;
    private final VLineTo up;

    public ScaleView(String text) {
        this();
        setText(text);
    }

    public ScaleView() {
        setMaxHeight(USE_PREF_SIZE); // don't resize beyond text size by default
        setMinHeight(USE_PREF_SIZE);

        text = new Label();

        // assemble path for line
        down = new VLineTo();
        up = new VLineTo();
        right = new HLineTo();

        down.setAbsolute(false);
        up.setAbsolute(false);
        right.setAbsolute(false);

        path = new Path(new MoveTo(), down, right, up);
        path.setStrokeWidth(2);
        path.setManaged(false);
        getChildren().addAll(text, path);
    }

    public final StringProperty textProperty() {
        return text.textProperty();
    }

    public final void setText(String value) {
        text.setText(value);
    }

    public final String getText() {
        return text.getText();
    }

    @Override
    protected void layoutChildren() {
        Insets insets = getInsets();

        double left = insets.getLeft();
        double top = insets.getTop();

        double h = getHeight() - top - insets.getBottom();
        double w = getWidth() - left - insets.getRight();

        // fix path
        down.setY(h);
        up.setY(-h);
        right.setX(w);
        path.relocate(left, top);

        layoutInArea(text,
                left, top,
                w, h,
                0,
                HPos.CENTER, VPos.CENTER);
    }

}

QuoteView

这有点复杂,因为箭头线居中并且使用了不同的笔触。在这种情况下,我将Polygon用作箭头,将Line用作两侧的垂直线和箭头线。

public class QuoteView extends Region {

    private final Line leftBound;
    private final Line rightBound;
    private final Line line;
    private final Label text;
    private final Polygon arrowLeft;
    private final Polygon arrowRight;
    private final Node[] hOrder;

    public QuoteView(String text) {
        this();
        setText(text);
    }

    public QuoteView() {
        text = new Label();

        line = new Line();

        // vertical lines
        leftBound = new Line();
        rightBound = new Line();
        leftBound.getStrokeDashArray().setAll(5d);
        rightBound.getStrokeDashArray().setAll(5d);

        // arrow heads
        final double arrowHeight = 15;
        final double arrowWidth = 10;
        arrowLeft = new Polygon(0, arrowHeight / 2, arrowWidth, 0, arrowWidth, arrowHeight);
        arrowRight = new Polygon(0, 0, arrowWidth, arrowHeight / 2, 0, arrowHeight);

        arrowLeft.setFill(null);
        arrowLeft.setStroke(Color.BLACK);
        arrowRight.setFill(null);
        arrowRight.setStroke(Color.BLACK);

        // nodes that contribute to horizontal size
        hOrder = new Node[]{ leftBound, arrowLeft, text, arrowRight, rightBound};

        getChildren().addAll(leftBound, arrowLeft, line, arrowRight, rightBound, text);
    }

    @Override
    protected double computePrefHeight(double width) {
        Insets insets = getInsets();

        double arrowHeight = arrowLeft.getLayoutBounds().getHeight();
        double textHeight = text.prefHeight(width);

        // preferred height is the height of the arrows
        // or 2*textHeight + arrow line height (higher value)
        return Math.max(arrowHeight,
                2 * textHeight + line.getLayoutBounds().getHeight()) + insets.getBottom() + insets.getTop();
    }

    @Override
    protected double computePrefWidth(double height) {
        Insets insets = getInsets();

        // the width is computed by putting the vertical lines, arrows and text next to each other
        double w = 0;
        for (Node n : hOrder) {
            w += n.prefWidth(height);
        }

        return w + insets.getLeft() + insets.getRight();
    }

    @Override
    protected double computeMinHeight(double width) {
        Insets insets = getInsets();

        double arrowHeight = arrowLeft.getLayoutBounds().getHeight();
        double textHeight = text.minHeight(width);

        // min height is the height of the arrows
        // or 2*textHeight + arrow line height (higher value)
        return Math.max(arrowHeight,
                2 * textHeight + line.getLayoutBounds().getHeight()) + insets.getBottom() + insets.getTop();
    }

    @Override
    protected double computeMinWidth(double height) {
        Insets insets = getInsets();

        // the width is computed by putting the vertical lines, arrows and text next to each other
        double w = 0;
        for (Node n : hOrder) {
            w += n.minWidth(height);
        }

        return w + insets.getLeft() + insets.getRight();
    }

    public final StringProperty textProperty() {
        return text.textProperty();
    }

    public final void setText(String value) {
        text.setText(value);
    }

    public final String getText() {
        return text.getText();
    }

    @Override
    protected void layoutChildren() {
        Insets insets = getInsets();

        double left = insets.getLeft();
        double top = insets.getTop();

        double h = getHeight();
        double w = getWidth();

        // set vertical line size
        double contentHeight = h - top - insets.getBottom();
        leftBound.setEndY(contentHeight);
        rightBound.setEndY(contentHeight);

        // layout left arrow & move left vertical line
        double x = left;
        leftBound.relocate(x, top);
        x += leftBound.getLayoutBounds().getWidth();
        Bounds bounds = arrowLeft.getLayoutBounds();
        arrowLeft.relocate(x, top + (contentHeight - bounds.getHeight()) / 2);
        x += bounds.getWidth();

        // layout right arrow & move right vertical line
        double xEnd = w - insets.getRight() - rightBound.getLayoutBounds().getWidth();
        rightBound.relocate(xEnd, top);
        bounds = arrowRight.getLayoutBounds();
        xEnd -= bounds.getWidth();
        arrowRight.relocate(xEnd, top + (contentHeight - bounds.getHeight()) / 2);

        // layout line
        double lineY = top + (contentHeight - line.getLayoutBounds().getHeight()) / 2;
        line.setStartX(x);
        line.setStartY(lineY);
        line.setEndX(xEnd);
        line.setEndY(lineY);

        // position text on top of the line
        layoutInArea(text,
                x, top,
                xEnd - x, lineY,
                0,
                HPos.CENTER, VPos.BOTTOM);
    }

}