JavaFX 获取单个调整大小事件

标签 java javafx javafx-8 javafx-2

这个问题相当简单:是否可以接收只触发一次的调整大小事件,即使 widthheight 同时改变?

我有一个应用程序可以计算每个像素窗口像素大小的图像。当窗口调整大小时,将再次计算图像。问题是,当监听 widthProperty()heightProperty() 时,总会触发两个事件,即使 widthheight 在同一个循环周期内改变。这导致一次冗余计算。有没有办法在每次更新时监听一次调整大小?

一个简单的例子:

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        Group root = new Group();

        primaryStage.setScene(new Scene(root));
        primaryStage.show();

        primaryStage.setWidth(800);
        primaryStage.setHeight(800);

        primaryStage.widthProperty().addListener((observable, oldValue, newValue) ->
                System.out.println("old: (" + oldValue + ", " + primaryStage.getHeight() + "); " 
                                 + "new: (" + newValue + ", " + primaryStage.getHeight() + ")")
        );

        primaryStage.heightProperty().addListener((observable, oldValue, newValue) ->
                System.out.println("old: (" + primaryStage.getWidth() + ", " + oldValue + "); " 
                                 + "new: (" + primaryStage.getWidth() + ", " + newValue + ")")
        );

        primaryStage.setWidth(400);
        primaryStage.setHeight(400);
    }
}

这打印:

old: (800.0, 800.0); new: (400.0, 800.0)
old: (400.0, 800.0); new: (400.0, 400.0)

但我只想将其作为输出:

old: (800.0, 800.0); new: (400.0, 400.0)

最佳答案

没有好的方法可以做到这一点。您可以使用 Platform.runLater() 进行一些黑客攻击来实现类似的效果。 .这是有效的,因为两个变化(宽度和高度)都是从同一个事件触发的,该事件在 Platform.runLater(...) 之前被完整处理。可以触发。将变量设置为 null 并忽略更改(如果它不为 null)可确保将来自同一事件的多个更改合并到对 Platform.runLater() 的单个调用中。 .

import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Point2D;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        Group root = new Group();

        primaryStage.setScene(new Scene(root));
        primaryStage.show();

        primaryStage.setWidth(800);
        primaryStage.setHeight(800);

        ChangeListener<Number> listener = new ChangeListener<Number>() {
            private Point2D stageSize = null ;
            private Point2D previousStageSize = new Point2D(primaryStage.getWidth(), primaryStage.getHeight());
            @Override
            public void changed(ObservableValue<? extends Number> arg0, Number arg1, Number arg2) {
                if (stageSize == null) {
                    Platform.runLater(() -> {
                        System.out.printf("Old: (%.1f, %.1f); new: (%.1f, %.1f)%n", 
                                previousStageSize.getX(), previousStageSize.getY(), 
                                stageSize.getX(), stageSize.getY());
                        previousStageSize = stageSize;
                        stageSize = null;
                    });
                }
                stageSize = new Point2D(primaryStage.getWidth(), primaryStage.getHeight());                
            }


        };

        primaryStage.widthProperty().addListener(listener);
        primaryStage.heightProperty().addListener(listener);


        primaryStage.setWidth(400);
        primaryStage.setHeight(400);
    }
}

虽然这可以说是有点 hack,但仅当没有其他未决更改时才处理更改可能正是您在此用例中所寻找的。

关于JavaFX 获取单个调整大小事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49512491/

相关文章:

java - 安卓 fragment

java - log4j:一次记录多个异常?

JavaFX 将抽象类对象添加到 arraylist

JavaFX 与 MySql 登录表单 - NullPointerException

JavaFX 线程卡住

javafx - 设置 JavaFX 表列名称填充

java - 如何在 JavaFX WebView 中显示 HTML 文档

java - Spring 安全出版

java - 如何编写 JUnit 测试用例而不从测试类传递参数

java - 当文本字段聚焦时,Windows 平板电脑触摸键盘不会弹出