简体   繁体   English

JavaFX将可调整大小的弧居中于边框中

[英]JavaFX center an resizable arc in a borderpane

I have a question. 我有个问题。 I am creating an application where an Arc length changes and I want that arc inside a borderpane, but when i change the length of the Arc it will get centered, so it doesn't look like a circle that's getting filled. 我正在创建一个应用程序,其中的弧长会发生变化,并且我希望该弧在边框窗格内,但是当我更改弧的长度时,它会居中,因此它看起来不像是一个被填充的圆。 Actually what i need is an arc and calculate it's position (the center of the borderpane) by it's maximum length (360). 实际上,我需要的是一条弧线,并通过其最大长度(360)计算其位置(边界窗格的中心)。 Can someone help me with this problem? 有人可以帮我解决这个问题吗? Thank you very much. 非常感谢你。

Create a Group. 创建一个组。 Place a rectangle in the group which is the size of a full circle (eg the rectangle's height and width is set to the circle's diameter), then add the arc to the group, with the arc layout position set to the circle's radius. 在组中放置一个矩形,该矩形是一个完整的圆的大小(例如,将矩形的高度和宽度设置为圆的直径),然后将弧添加到组中,并将弧的布局位置设置为圆的半径。 Place the Group in a StackPane so that the fixed size Group will be centered within a resizable Region. 将组放置在StackPane中,以使固定大小的组将在可调整大小的区域内居中。 Place the StackPane in the center of your BorderPane. 将StackPane放在BorderPane的中心。 Set the minimum size of the StackPane to zero so that it can be sized smaller than the Group, keeping the Group centered and clipped within it's visible bounds. 将StackPane的最小大小设置为零,以便其大小可以小于Group,同时保持Group居中并在其可见范围内进行裁剪。 Add some controls to the bottom of the BorderPane so that you can control the length of the arc dynamically. 在BorderPane的底部添加一些控件,以便可以动态控制弧的长度。

弧形图像

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.*;
import javafx.scene.control.Slider;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;

public class ArcControl extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        CenteredArc centeredArc = new CenteredArc();
        ArcControls arcControls = new ArcControls(centeredArc.getArc());

        BorderPane layout = new BorderPane();
        layout.setCenter(centeredArc.getArcPane());
        layout.setBottom(arcControls.getControlPane());

        stage.setScene(new Scene(layout));
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

class CenteredArc {
    private static final double INSET = 10;

    private static final double ARC_RADIUS = 100;
    private static final double INITIAL_ARC_LENGTH  = 60;
    private static final double ARC_STROKE_WIDTH = 10;
    private static final double ARC_REGION_SIZE =
            ARC_RADIUS * 2 + ARC_STROKE_WIDTH + INSET * 2;

    private final Arc arc;
    private final Pane arcPane;

    public CenteredArc() {
        // Create the arc.
        arc = new Arc(
                ARC_REGION_SIZE / 2, ARC_REGION_SIZE / 2,
                ARC_RADIUS, ARC_RADIUS,
                0,
                INITIAL_ARC_LENGTH
        );
        arc.setStrokeWidth(10);
        arc.setStrokeLineCap(StrokeLineCap.ROUND);
        arc.setStroke(Color.FORESTGREEN);
        arc.setFill(Color.POWDERBLUE);

        // Create a background fill on which the arc will be centered.
        // The paint of the background fill can be set to Color.TRANSPARENT
        // if you don't want the fill to be seen.
        final double fillSize = ARC_RADIUS * 2 + arc.getStrokeWidth() + INSET * 2;
        Rectangle fill = new Rectangle(fillSize, fillSize, Color.PINK);

        // Place the fill and the arc in the group.
        // The Group will be a fixed sized matching the fill size.
        Group centeredArcGroup = new Group(fill, arc);

        // place the arc group in a StackPane so it is centered in a resizable region.
        arcPane = new StackPane(centeredArcGroup);
        arcPane.setPadding(new Insets(INSET));
        arcPane.setMinSize(0, 0);
        arcPane.setStyle("-fx-background-color: papayawhip;");
    }

    public Arc getArc() {
        return arc;
    }

    public Pane getArcPane() {
        return arcPane;
    }
}

// helper class which can use a slider to control an arc.
class ArcControls {
    private static final double INSET = 10;

    private final Slider slider;
    private final VBox controlPane;

    public ArcControls(Arc arc) {
        slider = new Slider(0, 360, arc.getLength());
        controlPane = new VBox(
                slider
        );
        controlPane.setPadding(
                new Insets(INSET)
        );
        controlPane.setStyle(
                "-fx-background-color: palegreen;"
        );

        arc.lengthProperty().bind(slider.valueProperty());
    }

    public Slider getSlider() {
        return slider;
    }

    public VBox getControlPane() {
        return controlPane;
    }
}

Inside BorderPane (or StackPane) the alignment is done according to the bounding box of the shape (top left, center, bottom etc.). 在BorderPane(或StackPane)内部,对齐是根据形状的边界框(左上,中心,底部等)完成的。 Therefore the center point of the arc will move and will not give you the effect you want. 因此,圆弧的中心点将移动并且不会为您提供所需的效果。

Instead, put the arc inside an AnchorPane (if you want to use BorderPane, put AnchorPane inside a region (left, right, center etc.) of the BorderPane). 而是将弧线放置在AnchorPane中(如果要使用BorderPane,则将AnchorPane放置在BorderPane的区域(左,右,中心等)内)。 This will fix the center point of the arc even if you change the arc length and give you the effect of a circle getting filled with the increasing arc length. 即使您更改了弧长,这也将固定弧的中心点,并为您带来圆弧被增加的弧长填充的效果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM