动态背景JavaFX的霜冻玻璃效果

动态背景JavaFX的霜冻玻璃效果,javafx,cpu,blur,effect,panes,Javafx,Cpu,Blur,Effect,Panes,我正在开发一个JavaFX应用程序: 在这里,我希望左窗格具有模糊背景效果,即当用户滚动地图时,左窗格后面的内容会发生变化,我希望使用该内容(模糊)作为左窗格的背景我几乎做到了 每当我滚动地图时,它都会工作,并且后面的内容会得到更新,但是在系统监视器中,我可以看到CPU使用率、温度和总电源使用率急剧上升 为了实现霜玻璃效果,我在webEngine(包含地图)中添加了一个事件侦听器(用于检测鼠标移动): 侦听器执行以下方法: 检索左窗格(映射)下的实际内容 模糊是图像 更新屏幕 要更新屏幕,该方

我正在开发一个JavaFX应用程序:

在这里,我希望左窗格具有模糊背景效果,即当用户滚动地图时,左窗格后面的内容会发生变化,我希望使用该内容(模糊)作为左窗格的背景我几乎做到了

每当我滚动地图时,它都会工作,并且后面的内容会得到更新,但是在系统监视器中,我可以看到CPU使用率、温度和总电源使用率急剧上升

为了实现霜玻璃效果,我在webEngine(包含地图)中添加了一个事件侦听器(用于检测鼠标移动):

侦听器执行以下方法:

  • 检索左窗格(映射)下的实际内容

  • 模糊是图像

  • 更新屏幕

  • 要更新屏幕,该方法将删除左窗格(VBox)和上一个图像(即背景)然后再次,首先添加模糊图像窗格,然后将左窗格添加到根窗格

    因此,我认为我之所以会遇到性能问题,是因为在用户拖动地图时,它必须非常快速地将窗格(左窗格和背景图像)删除并添加到根窗格

    问题:非常高的CPU使用率

    那么,JavaFX中是否还有其他不需要如此高CPU使用率的方法


    例如,不需要一直删除和添加窗格。

    在HBox中创建两个窗格,在每个窗格中呈现地图相关部分的视图。在左窗格上设置模糊效果。不需要侦听器、快照或动态添加或删除窗格

    如果需要,可以使用不同的设置尝试两种不同的模糊效果(有BoxBlur和GuassianBlur),以调整性能特征

    直接在左窗格上设置模糊效果,模糊的所有内容(按钮文本),正如我设置的透明度效果,此设置仅在左窗格上设置模糊

    将stackpane用于左侧窗格,左侧贴图部分位于堆栈底部(应用模糊效果),透明覆盖层位于堆栈顶部(不应用效果)

    有没有办法,我可以模糊窗格的一部分,这样就可以选择并模糊位于左窗格下的部分

    是的,您使用的技术类似于:

    样品

    这是一个简单的示例,只是作为概念证明,显然对于您的解决方案,您需要一些稍微不同的东西


    你试过只设置左窗格的不透明度吗?是的,这是透明度效果,但我需要模糊效果。有人可能会补充说,模糊大面积通常是一种昂贵的效果。因此我在代码中对其进行了简化。我相信您建议在地图窗格和左窗格之间插入一个堆栈窗格,使其透明/半透明,然后对其应用模糊效果,并使左窗格透明,以便用户可以看到堆栈窗格的模糊效果。但这不起作用,可能是试图模糊堆栈窗格的透明颜色,而不是贴图内容的实际颜色。我是说将贴图一分为二,因此有两个节点。模糊地图的左分割部分。在StackPane中插入地图的左分割和(非模糊)覆盖。请参阅我提供的frost链接中的基于快照的冻结方法,尽管不使用快照也可以完成此操作。我不喜欢拆分地图,因为每个地图都需要单独的web视图和数据库连接,因此我尝试在左窗格和地图(webView)之间放置一个窗格,然后继续更新此窗格中的图像并使其模糊,因为我无法为我的应用程序移植冻结方法。谢谢您的帮助很好,有很多方法可以实现这一点,例如,将地图分割为两个左侧模糊的地图节点,或快照地图并覆盖模糊图像,或其他方法。您可以根据问题约束确定适当的方法。
    Document doc = webEngine.getDocument();
    ((EventTarget) doc).addEventListener("mousemove", listener, false);
    
    import javafx.application.Application;
    import javafx.geometry.Pos;
    import javafx.scene.Node;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.control.ScrollPane;
    import javafx.scene.effect.GaussianBlur;
    import javafx.scene.image.Image;
    import javafx.scene.image.ImageView;
    import javafx.scene.layout.StackPane;
    import javafx.scene.shape.Rectangle;
    import javafx.scene.text.TextAlignment;
    import javafx.stage.Stage;
    
    /**
     * Constructs a scene with a pannable Map background.
     */
    public class FrostedPannableView extends Application {
        private Image backgroundImage;
    
        private static final double W = 800;
        private static final double H = 600;
    
        @Override
        public void init() {
            backgroundImage = new Image("http://www.narniaweb.com/wp-content/uploads/2009/08/NarniaMap.jpg");
        }
    
        @Override
        public void start(Stage stage) {
            stage.setTitle("Drag the mouse to pan the map");
            stage.setResizable(false);
    
            // make a transparent pale blue overlay with non transparent blue writing on it.
            final Label label = new Label("Map\nof\nNarnia");
            label.setTextAlignment(TextAlignment.CENTER);
            label.setStyle("-fx-text-fill: midnightblue;  -fx-font: bold italic 40 'serif'; -fx-padding: 0 0 20 0;");
    
            StackPane glass = new StackPane();
            StackPane.setAlignment(label, Pos.BOTTOM_CENTER);
            glass.getChildren().addAll(label);
            glass.setStyle("-fx-background-color: rgba(0, 100, 100, 0.5);");
            glass.setMaxWidth(W * 1/4);
            glass.setMaxHeight(H);
            StackPane.setAlignment(glass, Pos.CENTER_LEFT);
    
            // construct a partitioned node with left side blurred.
            ImageView leftMap = new ImageView(backgroundImage);
            ImageView rightMap = new ImageView(backgroundImage);
    
            // wrap the partitioned node in a pannable scroll pane.
            ScrollPane leftScroll = createScrollPane(leftMap);
            Rectangle leftClip = new Rectangle(W * 1/4, H);
            leftScroll.setClip(leftClip);
            leftScroll.setEffect(new GaussianBlur());
    
            ScrollPane rightScroll = createScrollPane(rightMap);
            Rectangle rightClip = new Rectangle(W * 1/4, 0, W * 3/4, H);
            rightScroll.setClip(rightClip);
    
            StackPane composite = new StackPane();
            composite.getChildren().setAll(
                    leftScroll,
                    rightScroll
            );
    
            StackPane layout = new StackPane(
                    composite,
                    glass
            );
    
            // show the scene.
            Scene scene = new Scene(layout);
            stage.setScene(scene);
            stage.show();
    
            // bind the scroll values together and center the scroll contents.
            leftScroll.hvalueProperty().bind(rightScroll.hvalueProperty());
            leftScroll.vvalueProperty().bind(rightScroll.vvalueProperty());
            rightScroll.setHvalue(rightScroll.getHmin() + (rightScroll.getHmax() - rightScroll.getHmin()) / 2);
            rightScroll.setVvalue(rightScroll.getVmin() + (rightScroll.getVmax() - rightScroll.getVmin()) / 2);
        }
    
        /**
         * @return a ScrollPane which scrolls the node.
         */
        private ScrollPane createScrollPane(Node node) {
            ScrollPane scroll = new ScrollPane();
            scroll.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
            scroll.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
            scroll.setPannable(true);
            scroll.setMinSize(ScrollPane.USE_PREF_SIZE, ScrollPane.USE_PREF_SIZE);
            scroll.setPrefSize(W, H);
            scroll.setMaxSize(ScrollPane.USE_PREF_SIZE, ScrollPane.USE_PREF_SIZE);
            scroll.setContent(node);
            return scroll;
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }