1

在下面的代码中,我有一个 ToolBar,并向其中添加了各种大小的按钮。我希望按钮是方形的并且大小都一样。所以基本上从所有按钮中找到最长的宽度或高度,并将所有其他按钮的宽度和高度设置为这个大小。但是,按钮可以改变大小,所以我认为我需要一个绑定。我不太明白 - 有人知道怎么做吗?

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

public class ToolBarButtonTest extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        BorderPane borderPane = new BorderPane();
        Scene scene = new Scene(borderPane, 500, 500);

        ToolBar toolBar = new ToolBar();

        Button button1 = new Button("s");
        Button button2 = new Button("ss");
        Button button3 = new Button("sss");

        toolBar.getItems().addAll(button1, button2, button3);

        borderPane.setTop(toolBar);

        stage.setScene(scene);
        stage.show();
    }

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

谢谢,尼克。

4

2 回答 2

2

干得好。此示例将使用 CSS 将按钮形状变为正方形,并安装验证侦听器以跟踪按钮的布局更改并相应地更新宽度。

public class SquareButtons extends Application {
@Override
  public void start(final Stage stage) throws Exception {
    /* Assume these are your toolbar elements */
    final Button[] buttons = new Button[]{
            new Button("Short"),
            new Button("Slightly longer"),
            new Button("Very very very long button")
    };

    /* This would, of course, belong in a style sheet - it turns the buttons square */
    for (Button b : buttons)
        b.setStyle("-fx-background-radius: 0");

    /* This will set the pref width/height of all your buttons to the maximum of the pref width/height of the larget one */
    final InvalidationListener listener = new InvalidationListener() {
        public void invalidated(final Observable observable) {
            double size = 0;
            for (Button b : buttons) {
                size = Math.max(size, b.prefWidth(Integer.MAX_VALUE));
                size = Math.max(size, b.prefHeight(Integer.MAX_VALUE));
            }

            for (Button b : buttons) {
                b.setPrefWidth(size);
                b.setPrefHeight(size);
            }
        }
    };

    for (Button b : buttons)
        b.widthProperty().addListener(listener);

    final ToolBar toolbar = new ToolBar();
    toolbar.getItems().addAll(buttons);

    final Scene scene = new Scene(toolbar);
    stage.setScene(scene);
    stage.setWidth(800);
    stage.setHeight(200);
    stage.show();
  }

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

更新:没有充分阅读问题,请参阅评论。

于 2013-03-16T23:03:53.603 回答
0

由于没有其他人回应,我将传递一个部分解决方案。我是 JavaFX 的菜鸟,但由于父节点负责布局子节点,因此我将派生ToolBar该类的修改版本并覆盖一些布局代码。这是对您的示例的修改,它有效,但有点笨拙。

package toolbarbuttontest;

import javafx.application.Application;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ToolBar;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class ToolBarButtonTest extends Application {

    @Override
    public void start(Stage stage) {
        BorderPane borderPane = new BorderPane();
        Scene scene = new Scene(borderPane, 500, 500);

        Button btn1 = new Button("short");
        Button btn2 = new Button("between");
        Button btn3 = new Button("pretty long");

        SquareButtonToolBar toolBar = new SquareButtonToolBar();
        toolBar.getItems().addAll(btn1, btn2, btn3);

        borderPane.setTop(toolBar);

        stage.setScene(scene);
        stage.show();
        toolBar.requestLayout();
    }

    // A derivative of the ToolBar class that will resize all buttons to be
    // the same size (based on the length of the longest button label) and
    // square.
    class SquareButtonToolBar extends ToolBar {

        @Override
        protected void layoutChildren() {
            double minPrefSize = calculatePrefChildSize();
            for (Node n : getItems()) {
                if (n instanceof Button) {
                    ((Button) n).setPrefWidth(minPrefSize);
                    ((Button) n).setPrefHeight(minPrefSize);
                }
            }
            super.layoutChildren();
        }

        private double calculatePrefChildSize() {
            double minPrefSize = 0.0d;
            for (Node n : getItems()) {
                if (n instanceof Button) {
                    minPrefSize = Math.max(minPrefSize, n.prefWidth(-1));
                }
            }
            return minPrefSize;
        }

    }

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

该类SquareButtonToolBar通过将按钮的首选宽度和高度设置为最长按钮的长度来覆盖布局代码,从而使所有按钮都是正方形且大小相同。toolBar.requestLayout()kludge 是方法底部的调用start。如果没有这个调用,即使按钮宽度在程序启动时都显示为所需的宽度,但在重新调整窗口大小之前,高度不会正确显示。不知道我自己错过了什么。如果您找到答案,请发布更新。

更新:将示例修改为完全正常工作的示例,但带有令人讨厌的 kludge。

于 2013-03-16T22:02:43.700 回答