как можно обнаружить законченную операцию изменения размера в JavaFX?

У меня есть этап, a сцены и WebView узел. Когда я расширяю окно до большего размера-вещи становятся довольно вялыми из-за WebView. Что я хочу сделать, это заполнить новое пространство для WebView только когда изменение размера окна завершено (это я, отпуская левую кнопку мыши на изменяемом элементе управления/краю окна). Пока я могу просто установить максимум. размер этого узла что это по умолчанию-это остановит его от расширения. Но как я могу обнаружить в случае завершения операции изменения размера окна? С привязкой я могу проверить, что изменение размера происходит - но это мгновенно (свойства для W & D немедленно меняются без освобождения ЛКМ), в то время как я требую только действия, когда ЛКМ была отпущена. Предложения?


Я попытался с помощью addEventFilter на этап для событие.Любой, просто чтобы увидеть, распознается ли этот тип события - к сожалению, безрезультатно.

Я тоже наткнулся на этой сообщение без ответа.

3 ответов


этот ответ применяется только в том случае, если вы можете использовать undecorated Stage для вашего приложения.

с undecorated этапом вы можете обрабатывать изменения размеров украшения и операции самостоятельно; позволяя доступ к правым крючкам для обработки завершения операции изменения размера.

см. класс WindowResizeButton в пример приложения ансамбля исходный код для демонстрации того, как реализовать дескриптор изменения размера для undecorated ступень. Изменить этот класс, чтобы добавить setOnMouseReleased обработчик и реализовать изменения размера webView там.

Мне интересно, почему это необходимо, хотя, поскольку у меня на самом деле не было вялости, изменение размера окна, содержащего WebView - возможно, это связано с тем, что ваше приложение имеет другое использование контента в WebView от того, что я использовал.


это не прямой ответ на ваш вопрос. Если я правильно понял вялость, вы столкнулись с какими-то странными вспышками и визуализациями. Чтобы уменьшить вялость, размер webView можно обновить вручную и более редко:

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.layout.PaneBuilder;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.util.Duration;

public class KSO_Demo extends Application {

    @Override
    public void start(Stage primaryStage) {

        final WebView webView = new WebView();
        webView.getEngine().loadContent("<div style='background-color: gray; height: 100%'>Some content</div>");

        final Pane pane = PaneBuilder.create().children(webView).style("-fx-border-color: blue").build();

        final Timeline animation = new Timeline(
                new KeyFrame(Duration.seconds(.5),
                new EventHandler<ActionEvent>() {

                    @Override
                    public void handle(ActionEvent actionEvent) {
                        webView.setPrefSize(pane.getWidth(), pane.getHeight());
                    }
                }));
        animation.setCycleCount(1);

        primaryStage.setScene(new Scene(pane, 300, 250));

        primaryStage.widthProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> arg0, Number arg1, Number arg2) {
                animation.play();
            }
        });

        primaryStage.heightProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> arg0, Number arg1, Number arg2) {
                animation.play();
            }
        });
        primaryStage.show();
    }

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

webView находится в Pane который не раскладывает своих детей автоматически. Обновление размера webView задерживается .5 второе игнорирование обновлений в интервале.


Я делаю приложение, где мне нужно периодически получать спутниковые снимки (довольно интенсивные), поэтому мне пришлось найти способ захватить только последнее событие. Я решил создать поток для обратного отсчета в течение некоторого времени перед выполнением интенсивной задачи и прослушивателя изменения размера, который сбрасывает счетчик. Мне кажется более эффективным для меня, чем планирование и unscheduling задачи в сотни раз.

Примечание у меня также есть логика здесь, чтобы захватить первый window-size-изменение размера с помощью системы.currentTimeMillis();

import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;

public class ResizeListener implements ChangeListener {
    long lastdragtime = System.currentTimeMillis();
    double xi, yi, dx, dy, wid, hei;
    GuiModel model;
    TimerThread timebomb;

    public ResizeListener(GuiModel model) {
        this.model = model;
        timebomb = new TimerThread(350);
        timebomb.start();
    }

    public void changed(ObservableValue observable, Object oldValue, Object newValue) {
        if (System.currentTimeMillis() - lastdragtime > 350) { //new drag
            xi = model.stage.getWidth();
            yi = model.stage.getHeight();
            model.snapshot = model.canvas.snapshot(null, null);
        }

        timebomb.active = true;//start timer
        timebomb.ms = timebomb.starttime;//reset timer

        wid = model.stage.getWidth()-72;
        hei = model.stage.getHeight()-98;
        dx = model.stage.getWidth() - xi;
        dy = model.stage.getHeight() - yi;
        if (dx < 0 && dy < 0) {
            model.canvas.setWidth(wid);
            model.canvas.setHeight(hei);
            model.graphics.drawImage(model.snapshot, -dx/2, -dy/2, wid, hei, 0, 0, wid, hei);
        } else if (dx < 0 && dy >= 0) {
            model.canvas.setWidth(wid);
            model.graphics.drawImage(model.snapshot, -dx/2, 0, wid, hei, 0, 0, wid, hei);
        } else if (dx >= 0 && dy < 0) {
            model.canvas.setHeight(hei);
            model.graphics.drawImage(model.snapshot, 0, -dy/2, wid, hei, 0, 0, wid, hei);
        }
        lastdragtime = System.currentTimeMillis();
    }

    private class TimerThread extends Thread {
        public final int starttime;//multiple of 25
        public int ms = 0;
        public boolean active = false;

        public TimerThread(int starttime) {
            this.setDaemon(true);
            this.starttime = starttime;
        }

        public void run() {
            while (true) {
                try {
                    Thread.sleep(25);
                } catch (InterruptedException x) {
                    break;
                }

                if (active) {
                    ms -= 25;
                    if (ms <= 0) {
                        active = false;
                        Platform.runLater(() -> {
                            model.canvas.setWidth(wid);
                            model.canvas.setHeight(hei);
                            model.fetchSatelliteImagery();
                            model.refresh();
                        });
                    }
                }
            }
        }
    }//end TimerThread class
}//end listener class