7

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


我尝试在Event.ANY舞台上使用addEventFilter,只是为了查看此事件类型是否可识别 - 遗憾的是无济于事。

我也偶然发现了这个未答复的帖子。

4

3 回答 3

3

这不是您问题的直接答案。如果我正确理解了呆滞,那么您将面临某种奇怪的闪烁和效果图。为了减少延迟,可以手动更稀疏地更新 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 的大小更新延迟 0.5 秒,忽略间隔更新。

于 2012-07-07T23:24:18.927 回答
3

只有当您能够为您的应用程序使用未装饰的阶段时,此答案才适用。

使用未装饰的舞台,您可以自己处理调整大小的装饰和操作;允许访问正确的钩子以处理调整大小操作的完成。

请参阅Ensemble 示例应用程序源代码中的 WindowResizeButton 类,了解如何为未装饰的舞台实现调整大小句柄的演示。修改这个类以添加一个setOnMouseReleased处理程序并在其中实现您的 webView 大小修改。

我确实想知道为什么这是必要的,因为我在调整包含 WebView 的窗口大小时并没有任何迟缓 - 也许这是由于您的应用程序在 WebView 中的内容使用与我一直在使用的不同。

于 2012-07-08T06:42:06.457 回答
-1

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

注意我在这里也有一些逻辑来捕捉第一个窗口大小的变化 System.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
于 2015-04-22T18:33:28.813 回答