微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

JavaFX splitpane - 防止不必要的分隔线位置变化

如何解决JavaFX splitpane - 防止不必要的分隔线位置变化

我正在尝试找到一种方法,当其中一个分隔符受 maxWidth 属性约束时,可以防止分隔符位置发生变化。

在示例中,我单击一个按钮来最小化面板,并希望调整中央面板的大小以容纳额外的可用空间,但额外的空间在其他两个面板之间共享。

App at run

After clicking left button,right divider has moved

    @Override
public void start(Stage stage) {
    BooleanProperty clicked1 = new SimpleBooleanProperty(false);
    BooleanProperty clicked2 = new SimpleBooleanProperty(false);

    Button button1 = new Button("Click");
    button1.setonAction(event -> clicked1.set(!clicked1.get()));
    button1.setMaxWidth(800);

    Button button2 = new Button("Click");
    button2.setonAction(event -> clicked2.set(!clicked2.get()));
    button2.setMaxWidth(800);

    StackPane pane1  = new StackPane(button1);
    StackPane pane2 = new StackPane();
    StackPane pane3  = new StackPane(button2);

    pane1.maxWidthproperty().bind(Bindings.createDoubleBinding(() -> clicked1.get() ? 40.0 : Double.MAX_VALUE,clicked1));
    pane3.maxWidthproperty().bind(Bindings.createDoubleBinding(() -> clicked2.get() ? 40.0 : Double.MAX_VALUE,clicked2));

    SplitPane splitPane = new SplitPane(pane1,pane2,pane3);
    splitPane.setPrefSize(600,400);
    SplitPane.setResizableWithParent(pane1,false);
    SplitPane.setResizableWithParent(pane3,false);
    splitPane.setDividerPositions(0.25,0.75);

    stage.setScene(new Scene(splitPane));
    stage.show();
}

解决方法

您的问题的解决方案是根据修改后的窗格宽度计算和设置分隔线位置。

请在下面找到此逻辑的代码。包括关于要做什么的内联评论。

import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.SplitPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class SplitPaneIssue extends Application {

    private double COMPRESSED_WIDTH = 40.0;
    private double D1_DEFAULT_POSITION = 0.25;
    private double D2_DEFAULT_POSITION = 0.75;

    @Override
    public void start(Stage stage) {
        BooleanProperty clicked1 = new SimpleBooleanProperty();
        BooleanProperty clicked2 = new SimpleBooleanProperty();

        Button button1 = new Button("Click");
        button1.setOnAction(event -> clicked1.set(!clicked1.get()));
        button1.setMaxWidth(Double.MAX_VALUE);

        Button button2 = new Button("Click");
        button2.setOnAction(event -> clicked2.set(!clicked2.get()));
        button2.setMaxWidth(Double.MAX_VALUE);

        StackPane pane1 = new StackPane(button1);
        StackPane pane2 = new StackPane();
        StackPane pane3 = new StackPane(button2);

        SplitPane splitPane = new SplitPane(pane1,pane2,pane3);
        splitPane.setPrefSize(600,400);
        SplitPane.setResizableWithParent(pane1,false);
        SplitPane.setResizableWithParent(pane3,false);
        splitPane.setDividerPositions(D1_DEFAULT_POSITION,D2_DEFAULT_POSITION);

        clicked1.addListener((obs,old,val) -> {
            // First compute the total width of all panes and the percentage value per pixel
            double percentPerPx = 1 / (pane1.getWidth() + pane2.getWidth() + pane3.getWidth());
            // Set the max width based on the toggle value
            pane1.setMaxWidth(val ? COMPRESSED_WIDTH : Double.MAX_VALUE);

            // Now compute the divider positions with the new width.
            double d1 = val ? COMPRESSED_WIDTH * percentPerPx : D1_DEFAULT_POSITION;
            // Computing the width percentage for the pane3 and subtracting from 1 will retain its position.
            double d2 = 1 - (pane3.getWidth() * percentPerPx);
            splitPane.setDividerPositions(round(d1),round(d2));
        });
        clicked2.addListener((obs,val) -> {
            double percentPerPx = 1 / (pane1.getWidth() + pane2.getWidth() + pane3.getWidth());
            pane3.setMaxWidth(val ? COMPRESSED_WIDTH : Double.MAX_VALUE);
            double d1 = pane1.getWidth() * percentPerPx;
            double d2 = val ? 1 - (COMPRESSED_WIDTH * percentPerPx) : D2_DEFAULT_POSITION;
            splitPane.setDividerPositions(round(d1),round(d2));
        });
        stage.setScene(new Scene(splitPane));
        stage.show();
    }

    private double round(double value) {
        long factor = (long) Math.pow(10,2);
        value = value * factor;
        long tmp = Math.round(value);
        return (double) tmp / factor;
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?