【问题标题】:JavaFX GridPane resizing of pane childrenJavaFX GridPane 调整窗格子项的大小
【发布时间】:2014-03-10 11:01:08
【问题描述】:

可能是一个重复的问题,但我还没有找到适合我需要的解决方案。

jewelseaColorChooserSample 启发,在我的实现进行到一半时,我意识到手动大小只能在Controls 上设置,而不能在Panes 上设置。这些窗格应该足够智能,可以根据其父级自动调整大小。

有没有办法让GridPanes 的孩子同时抓住垂直和水平空间?很像 VBoxHBox 的组合。我敢打赌解决方案涉及AnchorPane

我的孩子是窗格而不是控件


带按钮的 SSCCE(复制 - 粘贴 - 运行 - 调整窗口大小)

import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Control;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

/**
 * 
 * @author ggrec
 *
 */
public class DashboardFXGrid extends Application
{

    // ==================== 1. Static Fields ========================

    private final static double GOLDEN_RATIO = 1.618;

    private final static double MIN_TILE_SIZE = 5;
    private final static double MAX_TILE_SIZE = Double.MAX_VALUE;


    // ====================== 2. Instance Fields =============================

    private DoubleProperty prefTileSize = new SimpleDoubleProperty(MIN_TILE_SIZE);

    private double nColumns;
    private double nRows;

    private GridPane gridPane;


    // ==================== 3. Static Methods ====================

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


    // ==================== 4. Constructors ====================

    @Override
    public void start(final Stage primaryStage) throws Exception
    {
        gridPane = new GridPane();

        gridPane.setPadding(new Insets(20));
        gridPane.setHgap(10);
        gridPane.setVgap(10);

        nColumns = Math.floor(Math.sqrt(dummyButtons().length) * 2 / GOLDEN_RATIO);
        nRows    = Math.ceil(dummyButtons().length / nColumns);

        createContents();

        addResizeListeners();

        primaryStage.setScene(new Scene(gridPane));
        primaryStage.show();
    }


    // ==================== 5. Creators ====================

    private void createContents()
    {
        int i = 0;

        for (final Button button : dummyButtons())
        {
            GridPane.setRowIndex(button,       i / (int) nColumns);
            GridPane.setColumnIndex(button, i % (int) nColumns);

            button.setMinSize(MIN_TILE_SIZE, MIN_TILE_SIZE);
            button.setMaxSize(MAX_TILE_SIZE, MAX_TILE_SIZE);

            gridPane.getChildren().add(button);

            i++;
        }
    }

    private void addResizeListeners()
    {
        gridPane.layoutBoundsProperty().addListener(new ChangeListener<Bounds>() {

            @Override public void changed(final ObservableValue<? extends Bounds> observableValue, final Bounds oldBounds, final Bounds newBounds)
            {
                prefTileSize.set(Math.max(MIN_TILE_SIZE, Math.min(newBounds.getWidth() / nColumns, newBounds.getHeight() / nRows)));

                for (final Node child : gridPane.getChildrenUnmodifiable())
                {
                    final Control tile = (Control) child;
                    tile.setPrefSize(prefTileSize.get(), prefTileSize.get());
                }
            }
        });
    }


    // ==================== 15. Other ====================

    private static final Button[] dummyButtons()
    {
        final Button[] buttons = new Button[5];

        for(int i = 0; i < buttons.length; i++)
        {
            buttons[i] = new Button(String.valueOf(i));
        }

        return buttons;
    }

}

【问题讨论】:

    标签: java javafx javafx-2


    【解决方案1】:

    有没有办法让 GridPanes 子级同时抓取​​垂直和水平空间?

    尝试使用GridPane的RowConstraintsColumnConstraints

    for (final Button button : dummyButtons()) {
        GridPane.setRowIndex(button, i / (int) nColumns);
        GridPane.setColumnIndex(button, i % (int) nColumns);
    
        button.setMinSize(MIN_TILE_SIZE, MIN_TILE_SIZE);
        button.setMaxSize(MAX_TILE_SIZE, MAX_TILE_SIZE);
    
        gridPane.getChildren().add(button);
    
        i++;
    }
    
    for (int j = 0; j < nColumns; j++) {
        ColumnConstraints cc = new ColumnConstraints();
        cc.setHgrow(Priority.ALWAYS);
        gridPane.getColumnConstraints().add(cc);
    }
    
    for (int j = 0; j < nRows; j++) {
        RowConstraints rc = new RowConstraints();
        rc.setVgrow(Priority.ALWAYS);
        gridPane.getRowConstraints().add(rc);
    }
    

    并且无需致电addResizeListeners()

    【讨论】:

    • 好的,这适用于Buttons (Controls)。现在Panes 怎么样?他们没有setMinSizesetMaxSize API。
    • @GGrec 你确定吗? Pane 有这些方法。
    • 哦,伙计……我很抱歉。你是对的,我写了一个愚蠢的评论。无论如何,您的答案似乎很有希望。我会回复你的。
    猜你喜欢
    • 1970-01-01
    • 2016-01-12
    • 2016-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-15
    • 2016-09-30
    • 1970-01-01
    相关资源
    最近更新 更多