当前位置: 首页 > 知识库问答 >
问题:

带有标题窗格的Java FX scroll pane panable property

慕容嘉熙
2023-03-14

我正在用javafx构建一个GUI应用程序,当用户从任何地方拖动它的内容时,它需要来自ScrollPane的PannableProperty来工作。

oracle文档中,他们提到了“pannableProperty”:

指定用户是否应该能够使用鼠标平移视区。如果鼠标事件到达ScrollPane(也就是说,如果鼠标事件没有被所包含的节点或其子节点之一阻止),则查询pannable以确定事件是否应该用于平移。

所以我的问题是鼠标事件无法到达ScrollPane...

有人知道如何使之成为可能吗?

这是一个简单的代码来测试它:

        ScrollPane root = new ScrollPane();
        root.setHbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
        root.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
        root.setPannable(true);

        VBox v = new VBox(10);

        TitledPane c1 = new TitledPane("test: ", new HBox(new Label("test: "), new TextField()));
        HBox c2 = new HBox(new Label("we are just in HBox  "), new TextField());
        Label c3 = new Label("I'm just a label and pannableProperty works here");
        TitledPane c4 = new TitledPane("test4", new HBox(new Label("test: "), new TextField()));
        AnchorPane c5 = new AnchorPane();
        c5.setPrefSize(100, 100);

        v.getChildren().addAll(c1, c2, c3, c4, c5);

        root.setContent(v);

        Scene scene = new Scene(root, 300, 300);
        primaryStage.setScene(scene);
        primaryStage.show();

共有1个答案

步德宇
2023-03-14

另一个棘手的问题:-)

< code>TitledPane的默认皮肤实现是< code>SkinBase的子类,默认构造函数(由< code>TitledPaneSkin调用)执行以下操作(简化版):

protected SkinBase(final C control) {       
    // Default behavior for controls is to consume all mouse events
    consumeMouseEvents(true);
}

所以我们需要扭转这种情况,不幸的是,你必须对此进行反思:

    TitledPane c1 = new TitledPane("test: ", new HBox(new Label("test: "), new TextField()));
    c1.skinProperty().addListener((w,o,n)-> {
        if(n instanceof SkinBase) {
            SkinBase<?> skinbase = (SkinBase<?>) n;
            try {
                Method m = SkinBase.class.getDeclaredMethod("consumeMouseEvents", Boolean.TYPE);

                AccessController.doPrivileged((PrivilegedAction<Void>) () -> {

                    boolean wasAccessible = m.isAccessible();
                    try {
                        m.setAccessible(true);
                        m.invoke(skinbase, false);
                        return null;
                    }
                    catch(ReflectiveOperationException e) { throw new IllegalStateException(e); }
                    finally {
                        m.setAccessible(wasAccessible);
                    }
                });
            } catch (ReflectiveOperationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    });

现在它应该工作了,至少在我的测试应用程序中是这样。

编辑#1:

这样做会重置鼠标操作期间的焦点,这会使标题窗格有些不可用。所以我们现在正在搞乱聚焦系统:

ScrollPane root = new ScrollPane();
root.setFocusTraversable(false);

Scene scene = new Scene(root, 300, 300);
scene.focusOwnerProperty().addListener((w,o,n)->
    if(n == root && o != null) {
        o.requestFocus();
    }
});

基本上,我们在这里做的是,如果新聚焦的元素是滚动窗格,我们将重新聚焦先前聚焦的组件。

 类似资料:
  • 我正在对Scene builder进行修补,以使UI设计得尽可能好,但我在JavaFX中定位标题窗格时遇到问题。正如您可能看到的,我有网格窗格内的标题窗格,锚窗格内的顶部,左侧和右侧锚定设置,和文本区的底部,左侧和右侧锚定设置。 我想要的:带标题窗格的网格窗格应该在顶部,当所有标题窗格折叠时,网格应该只有该窗格标签的高度。其余的空间应由文本区域占用。 我怎样才能做到这一点呢?

  • 我想让标题行有不同的颜色。到目前为止,我只是对字体有不同的颜色,因为背景颜色不能像我希望的那样工作。我的输出文件应为xls格式。 我尝试了命令,但这是igno。有没有另一种给背景着色的方法?

  • 我有一个 窗口,我从该窗口中删除了标题栏,并添加了一个自定义的“关闭”和“最小化”按钮。当程序首次加载时,它不会向任务栏显示图标。当我单击定制的最小化按钮时,它会在任务栏上创建一个图标;然而,当我单击恢复窗口时,我无法再次摆脱标题栏。 我希望图标始终显示在任务栏上,并且当程序最小化然后还原时,我希望标题栏仍然从 中消失。不幸的是,我很难在最小化之前和之后重置标志而不使任务栏图标消失。 请让我知道我

  • 我第一次使用JavaFX来尝试制作一个应用程序,我可以用它来演示一个带有按钮控件的简单动画。为此,我使用了BoarderPane作为初级阶段,左侧、右侧和底部都使用了GridPanes。 然而,对于中心,我需要能够画一个球内有一条线,我可以旋转不同的视图,同时能够动画,或至少快照移动内的线。 我试过用一个窗格做中心,但不起作用。我试着把它变成自己的场景和副场景,但都不起作用。我不能使用画布,因为它

  • 我正在我的flutter应用程序中实现一个DraggableScrollableSheet,并希望有一个粘性头,即只有列表视图滚动,工作表的顶部部分始终保持不变。我的小部件如下所示: 基本功能可以工作,但是,只有在拖动/滚动列表视图项时,工作表才是可拖动和可滚动的。我需要做什么更改来使列中的其他小部件也是可滚动的。我尝试了滚动和拖动小部件没有解决方案。 感谢任何帮助。