gpt4 book ai didi

带有 TitledPane 的 JavaFX ScrollPane PannableProperty

转载 作者:行者123 更新时间:2023-12-05 06:44:47 27 4
gpt4 key购买 nike

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

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

Specifies whether the user should be able to pan the viewport by using the mouse. If mouse events reach the ScrollPane (that is, if mouse events are not blocked by the contained node or one of its children) then pannable is consulted to determine if the events should be used for panning.

所以我的问题是鼠标事件无法到达 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();

最佳答案

另一个棘手的:-)

TitledPane 的默认 Skin 实现是 SkinBase 的子类,默认构造函数(由 TitledPaneSkin 调用)执行此操作 (缩短版):

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

所以我们需要扭转这个,不幸的是你必须为此做反射(reflection):

    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:

这样做会在鼠标操作期间重置焦点,这会导致 TitledPane 在某种程度上无法使用。所以我们现在正在搞乱焦点系统:

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();
}
});

基本上我们在这里所做的是,如果新获得焦点的元素是 ScrollPane,我们将重新获得先前获得焦点的组件的焦点。

关于带有 TitledPane 的 JavaFX ScrollPane PannableProperty,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27579663/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com