javafx - 在 Javafx 中,如何将网格窗格的大小单元格设置为父窗格的一小部分?
问题描述
我尝试在 JavaFx 中创建一个带有圆圈的 gridPane。我希望 gridPane 单元格使用 gridPane 中的所有可用空间。(GridPane 位于 BorderPane 的中心)但单元格不断调整大小以适应内部对象。如何让单元格使用所有可用空间?(以及如何将圆的半径设置为 BorderPane 中心可用空间的一小部分。
我对 JavaFx 很陌生,但我尝试使用 Columnconstraints 和 RowConstraints 来满足我的需要。它没有用。我还尝试在 GridPane 中绑定对象的大小以使用舞台大小的一小部分,但它无法正常工作,因为它与 BorderPane 中的平面不对应。
public void start(Stage primaryStage) throws Exception{
BorderPane applicationLayout = new BorderPane();
primaryStage.setTitle("Multi-level feedback simulator");
Scene scene = new Scene(applicationLayout, 600, 600);
primaryStage.setScene(scene);
//Add the menu Bar
//MainMenuBar menuBar = new MainMenuBar(primaryStage);
//applicationLayout.setTop(menuBar);
//Add the main zone of drawing
TreeDrawingZone treeDrawingZone = new TreeDrawingZone(primaryStage,applicationLayout,3,3);
applicationLayout.setCenter(treeDrawingZone);
primaryStage.show();
primaryStage.setMaximized(true);
}
带有约束的 GridPane 代码。构造函数的最大部分创建了线条和圆圈来显示一棵树。绘图函数是 createLine() 和 createCircle()
public class TreeDrawingZone extends Parent {
private GridPane drawingZoneLayout;
private Stage stage;
private int columnNumber;
private int rowNumber;
private Pane rootPane;
private List<Pair<Integer,Integer>> circlePositions;
public TreeDrawingZone(Stage stage,Pane rootPane, int treeHeight, int childrenPerNode){
this.stage = stage;
drawingZoneLayout = new GridPane();
columnNumber = 2*(int)Math.pow(childrenPerNode,treeHeight-1)-1;
rowNumber = 2*treeHeight-1;
circlePositions = new ArrayList<>();
this.rootPane = rootPane;
//TODO Use the correct height of the borderLayout (maybe with a upper level layout)
System.out.println(columnNumber);
System.out.println(rowNumber);
//column Constraints
for(int i = 1 ; i <= columnNumber ; i++){
ColumnConstraints columnConstraints = new ColumnConstraints();
columnConstraints.setPercentWidth((double) 100/columnNumber);
columnConstraints.setFillWidth(true);
drawingZoneLayout.getColumnConstraints().add(columnConstraints);
}
//row Constraints
for(int i = 1 ; i <= rowNumber ; i++){
RowConstraints rowConstraints = new RowConstraints();
rowConstraints.setPercentHeight((double) 100/rowNumber);
rowConstraints.setFillHeight(true);
drawingZoneLayout.getRowConstraints().add(rowConstraints);
}
//Tree Representation
//Base Line
List<Integer> circleLineRepartition = new ArrayList<>();
for(int i = 0 ; i < columnNumber; i ++){
if(i % 2 == 0){
circleLineRepartition.add(i);
}
}
System.out.println(circleLineRepartition);
//Creation of the grid line per line
for(int i = rowNumber-1 ; i >=0 ; i-=2){
if(i % 2 == 0) {
//Case of the line with circles
for (Integer circlePosition : circleLineRepartition) {
Pane circlePane;
if (i == 0) {
circlePane = createCircle(true, false);
} else if (i == rowNumber - 1) {
circlePane = createCircle(false, true);
} else {
circlePane = createCircle();
}
drawingZoneLayout.add(circlePane, circlePosition, i);
circlePositions.add(new Pair<>(circlePosition, i));
}
List<Integer> upperCircleLineRepartition;
//Create the lines
//The following block enumerates the different cases to create the lines between the dotes
try {
upperCircleLineRepartition = getoddlyRepartedCenters(childrenPerNode, circleLineRepartition);
if (i > 0) {
int minPosition = circleLineRepartition.get(0);
int maxPosition = circleLineRepartition.get(circleLineRepartition.size() - 1);
int position = 0;
boolean drawHorizontal = true;
int linkedNodeCount = 0;
for (int j = minPosition; j <= maxPosition; j++) {
Pane linesPane;
if (j == circleLineRepartition.get(position) && minPosition != maxPosition) {
//Update the number of linked Nodes
if(drawHorizontal) {
linkedNodeCount += 1;
if(linkedNodeCount == childrenPerNode)
drawHorizontal = false;
}else{
linkedNodeCount = 1;
drawHorizontal = true;
}
//First element
if (linkedNodeCount == 1) {
if(upperCircleLineRepartition.contains(j)){
linesPane = createLines(LineDirection.NORTH,LineDirection.SOUTH,LineDirection.EAST);
}else {
linesPane = createLines(LineDirection.SOUTH, LineDirection.EAST);
}
}
//Last element
else if (linkedNodeCount == childrenPerNode) {
if(upperCircleLineRepartition.contains(j)){
linesPane = createLines(LineDirection.NORTH,LineDirection.SOUTH,LineDirection.WEST);
}else {
linesPane = createLines(LineDirection.WEST, LineDirection.SOUTH);
}
}//bridge with under and upper level
else if(upperCircleLineRepartition.contains(j)) {
linesPane = createLines(LineDirection.SOUTH, LineDirection.NORTH, LineDirection.EAST, LineDirection.WEST);
}
//other children
else{
linesPane = createLines(LineDirection.SOUTH, LineDirection.EAST, LineDirection.WEST);
}
position++;
}
//Only one child
else if (minPosition == maxPosition) {
linesPane = createLines(LineDirection.SOUTH, LineDirection.NORTH);
}
//Bridge between children
else {
if(drawHorizontal) {
if (upperCircleLineRepartition.contains(j)) {
linesPane = createLines(LineDirection.NORTH, LineDirection.EAST, LineDirection.WEST);
} else {
linesPane = createLines(LineDirection.WEST, LineDirection.EAST);
}
}else{
linesPane = createLines();
}
}
drawingZoneLayout.add(linesPane, j, i - 1);
}
}
circleLineRepartition = new ArrayList<>(upperCircleLineRepartition);
} catch (Exception e) {
System.out.println("Invalid line given");
}
}
}
drawingZoneLayout.setMaxSize(Region.USE_COMPUTED_SIZE, Region.USE_COMPUTED_SIZE);
//TODO remove GridLines after debug
drawingZoneLayout.setGridLinesVisible(true);
this.getChildren().add(drawingZoneLayout);
}
private Pane createCircle(){
return createCircle(false,false);
}
private Pane createCircle(boolean isRoot, boolean isLeaf){
Pane circlePane = new Pane();
Circle circle = new Circle();
circle.centerXProperty().bind(stage.widthProperty().divide(columnNumber).divide(2));
circle.centerYProperty().bind(stage.heightProperty().divide(rowNumber).divide(2));
circle.radiusProperty().bind(Bindings.min(stage.widthProperty().divide(columnNumber).divide(2),stage.heightProperty().divide(rowNumber).divide(2)));
circlePane.getChildren().add(circle);
if(!isLeaf) {
circlePane.getChildren().add(createLines(LineDirection.SOUTH));
}
if(!isRoot){
circlePane.getChildren().add(createLines(LineDirection.NORTH));
}
return circlePane;
}
private Pane createLines(LineDirection ... directions){
Pane linesGroup = new Pane();
for(LineDirection direction : directions){
linesGroup.getChildren().add(createLine(direction));
}
return linesGroup;
}
private Line createLine(LineDirection direction){
Line line = new Line();
if(direction == LineDirection.EAST || direction == LineDirection.WEST){
line.startYProperty().bind(stage.heightProperty().divide(rowNumber).divide(2));
line.endYProperty().bind(stage.heightProperty().divide(rowNumber).divide(2));
line.startXProperty().bind(stage.widthProperty().divide(columnNumber).divide(2));
if(direction == LineDirection.EAST){
line.endXProperty().bind(stage.widthProperty().divide(columnNumber));
}
else{
line.setEndX(0);
}
}
else{
line.startXProperty().bind(stage.widthProperty().divide(columnNumber).divide(2));
line.endXProperty().bind(stage.widthProperty().divide(columnNumber).divide(2));
line.startYProperty().bind(stage.heightProperty().divide(rowNumber).divide(2));
if(direction == LineDirection.NORTH){
line.setEndY(0);
}else{
line.endYProperty().bind(stage.heightProperty().divide(rowNumber));
}
}
line.setStrokeWidth(1);
line.setFill(null);
line.setStroke(Color.BLACK);
return line;
}
private int getCenter(List<Integer> childrenNodesPosition) throws Exception {
if (childrenNodesPosition.size() == 0){
throw new Exception("Tried to get the center of an empty list");
}else{
int sum = 0;
for(int childNodePosition : childrenNodesPosition){
sum += childNodePosition;
}
return sum/childrenNodesPosition.size();
}
}
private List<Integer> getoddlyRepartedCenters(int nodeNumberPerParent, List<Integer> childrenNodesPosition) throws Exception {
int parentNumber = childrenNodesPosition.size()/nodeNumberPerParent;
int nextPosition = 0;
List<Integer> regularParentCenters = new ArrayList<>(parentNumber);
for(int i = 0 ; i < parentNumber ; i++){
regularParentCenters.add(getCenter(childrenNodesPosition.subList(nextPosition,nextPosition + nodeNumberPerParent)));
nextPosition = nextPosition + nodeNumberPerParent;
}
return regularParentCenters;
}
}
解决方案
推荐阅读
- nginx - 将 nginx /index.html 重定向到 root 导致无限重定向
- ssl - IIS 7.5 问题 LetsEncrypt HTTP 验证由于不提供无扩展名文件
- java - 使用 Maven、jpa 和 javaFX 构建项目
- r - R中条形图中的文本
- laravel - laravel如何根据自定义数据库查询添加验证规则
- python - Pandas:如何总结 pandas 交叉表/频率矩阵
- java - 循环内输入的时间限制
- javascript - Vue.js - 如果模型拒绝更改,则恢复输入值
- powershell - PowerShell 点击表单提交 URL 不正确
- sql - 将 SQL 选择语句与 ASM 磁盘组的 in 运算符连接起来