JavaFX ScrollPane PickOnBounds(部分鼠标透明)

问题描述 投票:2回答:1

我目前正在基于JavaFX的GUI程序上进行视频编辑。在这里,我遇到了ScrollPane的问题。我无法弄清楚如何使ScrollPane(正确)接界。这意味着我实际上可以单击ScrollPane到下面的Node上。我认为这可能与ScrollPane的视口有关。我试图在下面给出我们程序的简化版本:

Styles.css

.scroll-pane > .viewport {
    -fx-background-color: transparent;
    -fx-background-radius: 4;
}

sample.fxml

<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.control.ScrollPane?>

<StackPane
  xmlns:fx="http://javafx.com/fxml"
  xmlns="http://javafx.com/javafx"
  fx:controller="sample.Controller" fx:id="myStackPane">
    <Pane onMousePressed="#onMouseInteraction" style="-fx-background-color: red"/>
    <AnchorPane fx:id="markerIconPane" pickOnBounds="false">
        <ScrollPane style="-fx-background-color: transparent" pickOnBounds="false" vbarPolicy="ALWAYS" hbarPolicy="ALWAYS"/>
    </AnchorPane>
</StackPane>

Controller.java

package sample;

import javafx.scene.input.MouseEvent;
import javafx.fxml.FXML;

public class Controller implements Initializable {
    //...
    public void onMouseInteraction(MouseEvent mouseEvent) {
        System.out.println(mouseEvent.getX());
    }
}

Main.java

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        root.getStylesheets().add("./Styles.css");
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();
    }

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

现在您可以清楚地看到左上方的滚动条。当您按下滚动条外部的红色时,会调用onMouseInteraction(),但是当您按下滚动条内部时,什么也不会发生。

谢谢菲利普

java javafx scrollpane
1个回答
1
投票

假设Pane要素是您提到的视口;您可以将onMouseInteraction处理程序作为EventFilter添加到堆栈窗格中,以便它位于正确的事件链中。例如:

myStackPane.addEventFilter(Controller::onMouseInteraction) ;

那样,Pane不需要作为额外的事件层,尽管缺点是您无法仅从fxml文件添加EventFilter。但是,您也可以在控制器的init方法中添加该语句。

如果要在Pane中进行视觉叠加,可以将其mouseTransparent属性设置为true。这样,它就不会干扰事件(就像它不在那儿一样)

如果无法将EventFilter放入事件链中,那么实际上不是一个好的解决方案。在javafx8中,我通过使用修改后的PickResult传播事件来“入侵”系统。但是在以后的版本中,已使用(已描述)的方法已设为私有(即,没有大量反射就无法使用)。

© www.soinside.com 2019 - 2024. All rights reserved.