为了账号安全,请及时绑定邮箱和手机立即绑定

Javafx 儿童溢出 FlowPane

Javafx 儿童溢出 FlowPane

白板的微信 2023-03-23 15:10:46
我正在重做一个我用处理做的项目,因为我想在 JavaFX 中进行一些练习,因为明年我将在 uni 中需要它,它会给我更多的 ui 比处理更多的自由。这意味着我不熟悉使用 javafx 做事,抱歉。我想在我的主窗口中有一个容器来容纳一些窗格。在这些窗格上,我稍后会单独使用。我选择了 FlowPane,较小的窗格只是,嗯,窗格。我希望如果窗口的大小发生变化,则会创建(删除)更多的窗格,并且始终在容器上显示完美数量的窗格(这有点难以解释,但请查看链接的图片下面,你就会明白了)。这在 99% 的时间里工作得很好,但有时窗格会溢出流程窗格。我尝试了很多来解决这个问题(几乎是蛮力解决的,哈哈),但我找不到比这更好的了。不良行为期望的行为项目的Github如果你想自己尝试控制器代码:public class MainWindowController {    private int sizeOfOneGame = 100; //In pixel    //Space between the frame of the Pane that holds all games and the games    private int[] paddingAroundGames = {30, 30, 30, 30}; //Top, Right, Bottom, Left    //Space between two games    private int[] gapBetweenGames = {10, 10}; //X, Y    @FXML    FlowPane flowPaneGames;    public void initialize(){        //Sets space between two games in the flowPane        flowPaneGames.setHgap(gapBetweenGames[0]);        flowPaneGames.setVgap(gapBetweenGames[1]);        //Sets space between all games and the border of the flowPane        flowPaneGames.setPadding(new Insets(paddingAroundGames[0], paddingAroundGames[1], paddingAroundGames[2], paddingAroundGames[3]));        //Draws one frame around the flowPane        flowPaneGames.setStyle("-fx-border-color: black");        //Aligns the panes to the center        flowPaneGames.setAlignment(Pos.BASELINE_CENTER);        //Adds listeners to the width and height of the flowPane holding the games -> Adjusts shown Panes on size change        flowPaneGames.widthProperty().addListener(e -> flowPaneGamesSizeChanged());        flowPaneGames.heightProperty().addListener(e -> flowPaneGamesSizeChanged());    }    }如果有人能帮我解决这个问题,我会很高兴(即使它只在少数情况下发生),这真的让我很困扰。旁注:我已经在这里问过这个问题,但我几乎没有努力解决几乎没有任何答案的问题,这次我试图做得更好。人们还抱怨说我没有真正遵循 Java 的命名约定,我试着听听它并希望代码现在更容易阅读。
查看完整描述

1 回答

?
慕村225694

TA贡献1880条经验 获得超4个赞

问题的原因是没有考虑到容器的边框宽度。考虑到容器的边框宽度,totalSpaceX必须totalSpaceY按如下方式确定:

int totalSpaceX = (int) (flowPaneGames.getWidth() - paddingAroundGames[1] - paddingAroundGames[3] + gapBetweenGames[0] - flowPaneGames.getBorder().getStrokes().get(0).getWidths().getLeft() - flowPaneGames.getBorder().getStrokes().get(0).getWidths().getRight());
int totalSpaceY = (int) (flowPaneGames.getHeight() - paddingAroundGames[0] - paddingAroundGames[2] + gapBetweenGames[1] - flowPaneGames.getBorder().getStrokes().get(0).getWidths().getTop() - flowPaneGames.getBorder().getStrokes().get(0).getWidths().getBottom());

左图显示了492每个容器的高度和宽度,其中考虑了容器的边框宽度。容器的边框宽度是1默认的。刚好有 4 个子窗格适合宽度:492 = 2 x border width of container (= 1) + 2 * padding (= 30) + 3 * gap (= 10) + 4 * child pane width (= 100). 这同样适用于高度。

如果宽度和/或高度减少1,则1宽度和/或高度中的每个子窗格都将被省略。中间的图显示了491考虑到容器的边框宽度的每个容器的高度和宽度。

如果不考虑容器的边框宽度,则假定的空间比实际可用的空间多,并且会创建过多的子窗格。右图显示了491每个容器的高度和宽度,没有考虑边框宽度(即它显示了当前代码的作用)。

//img1.sycdn.imooc.com//641bfbdb0001009310620380.jpg

编辑:

根据@Slaw 的建议,totalSpaceX可以totalSpaceY使用以下方法更轻松地进行计算Region#snappedXXXInset()

int totalSpaceX = (int) (flowPaneGames.getWidth() - flowPaneGames.snappedLeftInset() - flowPaneGames.snappedRightInset() + gapBetweenGames[0]);
int totalSpaceY = (int) (flowPaneGames.getHeight() - flowPaneGames.snappedTopInset() - flowPaneGames.snappedBottomInset() + gapBetweenGames[1]);

snapToPixel应该设置(这是默认值)。


查看完整回答
反对 回复 2023-03-23
  • 1 回答
  • 0 关注
  • 68 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信