如何在JavaFX中检测已完成的大小调整操作?

如何在JavaFX中检测已完成的大小调整操作?,java,javafx-2,resize,stage,scene,Java,Javafx 2,Resize,Stage,Scene,我有一个舞台、一个场景和一个网络视图节点。当我将窗口扩大到更大的尺寸时,由于WebView,事情变得非常缓慢。我要做的是,仅当窗口的大小调整完成时(这是我在窗口的可调整大小控件/边缘上释放鼠标左键),才填充WebView的新空间。现在,我可以将这个节点的最大大小设置为默认值-这将阻止它扩展。但是,如何检测窗口上已完成的调整大小操作的实际事件?通过绑定,我可以验证是否进行了大小调整,但这是瞬时的(W&D的属性会立即更改,而不会释放LMB),而我只需要在LMB已释放时执行操作。建议 我尝试在舞台上

我有一个舞台、一个场景和一个网络视图节点。当我将窗口扩大到更大的尺寸时,由于WebView,事情变得非常缓慢。我要做的是,仅当窗口的大小调整完成时(这是我在窗口的可调整大小控件/边缘上释放鼠标左键),才填充WebView的新空间。现在,我可以将这个节点的最大大小设置为默认值-这将阻止它扩展。但是,如何检测窗口上已完成的调整大小操作的实际事件?通过绑定,我可以验证是否进行了大小调整,但这是瞬时的(W&D的属性会立即更改,而不会释放LMB),而我只需要在LMB已释放时执行操作。建议


我尝试在舞台上为事件使用addEventFilter


我还偶然发现了一篇未回复的帖子。

这不是对你问题的直接回答。如果我正确理解了这种迟钝,那么你正面临着某种奇怪的闪光和渲染。为了减少迟钝,可以手动更新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);
    }
}
导入javafx.animation.KeyFrame;
导入javafx.animation.Timeline;
导入javafx.application.application;
导入javafx.beans.value.ChangeListener;
导入javafx.beans.value.observeValue;
导入javafx.event.ActionEvent;
导入javafx.event.EventHandler;
导入javafx.scene.scene;
导入javafx.scene.layout.Pane;
导入javafx.scene.layout.PaneBuilder;
导入javafx.scene.web.WebView;
导入javafx.stage.stage;
导入javafx.util.Duration;
公共类KSO_演示扩展了应用程序{
@凌驾
公共无效开始(阶段primaryStage){
最终WebView WebView=新WebView();
webView.getEngine().loadContent(“某些内容”);
最终窗格=PaneBuilder.create().children(webView).style(“-fx边框颜色:蓝色”).build();
最终时间线动画=新时间线(
新关键帧(持续时间.s(.5),
新的EventHandler(){
@凌驾
公共无效句柄(ActionEvent ActionEvent){
setPrefSize(pane.getWidth(),pane.getHeight());
}
}));
动画。setCycleCount(1);
初始阶段。设置场景(新场景(窗格,300250));
primaryStage.widthProperty().addListener(新的ChangeListener()){
@凌驾

public void changed(observevalue此答案仅适用于您能够在应用程序中使用的情况

使用未装饰的阶段,您可以自己处理调整大小的装饰和操作;允许访问正确的挂钩来处理调整大小操作的完成

请参阅源代码中的WindowResizeButton类,了解如何为未装饰的阶段实现调整大小句柄的演示。修改该类以添加处理程序并在其中实现webView大小修改


我确实想知道为什么这是必要的,因为我在调整包含WebView的窗口时并没有遇到任何迟钝的问题——也许这是因为您的应用程序在WebView中的内容使用情况与我一直使用的不同。

我正在制作一个应用程序,我必须定期获取卫星图像(相当密集),因此我必须找到一种方法来捕获最后一个事件。我决定在执行密集型任务之前,生成一个线程来倒计时一段时间,并重新调整侦听器的大小以重置计数。对我来说,这似乎比数百次计划和非计划任务更有效

注意,我这里还有一些逻辑来捕获System.currentTimeMillis()的第一个窗口大小更改

导入javafx.application.Platform;
导入javafx.beans.value.ChangeListener;
导入javafx.beans.value.observeValue;
公共类ResizeListener实现ChangeListener{
long lastdragtime=System.currentTimeMillis();
双席,易,DX,DY,WID,HEI;
gui模型;
定时炸弹;
公共ResizeListener(GUI模型){
this.model=模型;
定时炸弹=新定时器读数(350);
定时炸弹;
}
公共无效已更改(可观察值可观察、对象旧值、对象新值){
如果(System.currentTimeMillis()-lastdragtime>350){//新拖动
席=模型。
yi=model.stage.getHeight();
model.snapshot=model.canvas.snapshot(null,null);
}
timebomb.active=true;//启动计时器
timebomb.ms=timebomb.starttime;//重置计时器
wid=model.stage.getWidth()-72;
hei=model.stage.getHeight()-98;
DX= Mult.Field.GigWistHe()席;
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);
}否则如果(dx<0&&dy>=0){
model.canvas.setWidth(wid);
model.graphics.drawImage(model.snapshot,-dx/2,0,wid,hei,0,0,wid,hei);
}否则如果(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();
}
私有类TimerThread扩展线程{
public final int starttime;//25的倍数
公共整数ms=0;
公共布尔活动=假;
公共时间读取(int starttime){
this.setDaemon(true);
this.starttime=starttime;
}
公开募捐{
而
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