将节点放在圆圈中

时间:2015-06-02 14:15:41

标签: java javafx

我正在尝试像这样布局我的节点: //TODO Insert picture here 这是我当前的布局,名为CircularPane

import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.layout.Pane;

public class CircularPane extends Pane {
    @Override
    protected void layoutChildren() {
        final int radius = 50;
        final double increment = 360 / getChildren().size();
        double degreese = 0;
        for (Node node : getChildren()) {
            double x = radius * Math.cos(Math.toRadians(degreese)) + getWidth() / 2;
            double y = radius * Math.sin(Math.toRadians(degreese)) + getHeight() / 2;
            layoutInArea(node, x - node.getBoundsInLocal().getWidth() / 2, y - node.getBoundsInLocal().getHeight() / 2, getWidth(), getHeight(), 0.0, HPos.LEFT, VPos.TOP);
            degreese += increment;
        }
    }
}

这是我的主要课程:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;

public class Main extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) {
        CircularPane pane = new CircularPane();
        for(int i = 0; i < 6; i++) {
            Button button = new Button("" + i);
            pane.getChildren().add(button);
        }
        stage.setScene(new Scene(pane));
        stage.show();
    }
}

这是我目前的展示:

enter image description here

节点不在底部接触,它们在圆圈周围均匀分布。我想做到这一点,所以他们走到了尽头,但无法弄清楚如何。

1 个答案:

答案 0 :(得分:2)

您在圆圈上布置按钮的方法是正确的,但在这一行中您将定义它们的布局方式:

final double increment = 360 / getChildren().size();

这给出了从圆心中提到的任意两个按钮之间的相同角度!这就是你获得当前显示效果的原因。

如果你想像图中那样布置节点,如果我做对了,那就是条件:

  • 每个节点都以圆圈为中心
  • 节点在水平方向上是等分的:水平间隙从0到某个值。
  • 从圆圈到第一个节点的初始间隙从0变为某个值。
  • 可以调整每个节点的大小以满足先前的条件

因此,让我们为这些值定义一些字段,并调整窗格的大小:

class CircularPane extends Pane {

    private final double radius;
    private final double ext_gap;
    private final double int_gap;

    public CircularPane(double radius, double ext_gap, double int_gap){
        this.radius=radius;
        this.ext_gap=ext_gap;
        this.int_gap=int_gap;

        setMinSize(2*radius, 2d*radius);
        setPrefSize(2*radius, 2d*radius);
        setMaxSize(2*radius, 2d*radius);
    }
}

现在,给定任何n按钮,上述条件可以转换为一个解决节点大小的方程式。如果总可用长度(2*radius)减去两个外部间隙(2*ext_gap)与n个按钮大小buttonSizen-1内部间隙(int_size ),然后,每个按钮的大小必须是:

@Override
protected void layoutChildren() {
    int n=getChildren().size();
    double buttonSize = (2*radius-2*ext_gap-(n-1)*int_gap)/n;
}

最后,现在您可以设置按钮的大小并布局每个节点,只需增加x坐标(按钮的大小加上内部间隙),然后获取{{1} }来自圆等式的坐标:

y

请注意,您还可以更改字体的大小,以获得任意大小的按钮的可见数字。

另请注意,@Override protected void layoutChildren() { int n=getChildren().size(); double buttonSize = (2*radius-2*ext_gap-(n-1)*int_gap)/n; double x=ext_gap+buttonSize/2d, y; for (Node node : getChildren()) { ((Button)node).setMinSize(buttonSize, buttonSize); ((Button)node).setPrefSize(buttonSize, buttonSize); ((Button)node).setMaxSize(buttonSize, buttonSize); node.setStyle("-fx-font-size: "+Math.round(buttonSize/3)); node.setManaged(false); y=getHeight()/2d+Math.sqrt(radius*radius-Math.pow(x-radius,2d)); layoutInArea(node, x-buttonSize/2d, y-buttonSize/2d, getWidth(), getHeight(), 0.0, HPos.LEFT, VPos.TOP); x+=buttonSize+int_gap; } } 可以避免在您点击按钮时调用node.setManaged(false);(由于点击或点击时点击按钮大小的变化)。

最后,这将创建一个圆形窗格并绘制一个圆圈:

layoutChildren()

结果如下:

CirclePane