Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can one detect a finished resizing operation in JavaFX?

I have a stage, a scene and a WebView node. When I expand the window to a larger size - things get pretty sluggish due to WebView. What I want to do is fill the new space for WebView only when the resizing of the window has been finished (this is me releasing left mouse button on the resizable control/edge of the window). For now I can just set the max. size of this node to what it is by default - this will stop it from expansion. But how can I detect the actual event of a completed resizing operation on the window? With binding, I can verify that the resizing takes place - but it's instantaneous (properties for W & D change immediately w/o releasing LMB), while I only require an action when the LMB has been released. Suggestions?


I tried using an addEventFilter on the stage for Event.ANY, just to see if this event type is recognizable - sadly with no avail.

I've also stumbled upon this unanswered post.

like image 603
XXL Avatar asked Jul 07 '12 18:07

XXL


People also ask

How do I stop windows from resizing JavaFX?

You can do it with stage. setResizable(false); You can also remove window buttons with stage.

How do you end a JavaFX program?

The static exit() method in the Platform class is the preferred way to programmatically end a JavaFX program. It is preferred to System. exit() because it cleanly shuts down the application thread and gives it an opportunity to clean up by calling the application's stop() method before terminating.

What method is invoked to display a stage in JavaFX?

Showing a Stage The difference between the JavaFX Stage methods show() and showAndWait() is, that show() makes the Stage visible and the exits the show() method immediately, whereas the showAndWait() shows the Stage object and then blocks (stays inside the showAndWait() method) until the Stage is closed.


2 Answers

This answer is only applies if you are able to use an undecorated Stage for your application.

With an undecorated stage you can handle the resizing decorations and operations yourself; allowing access to the right hooks for handling the completion of a resize operation.

See the WindowResizeButton class in the Ensemble sample application source code for a demo of how to implement a resize handle for an undecorated stage. Modify this class to add a setOnMouseReleased handler and implement your webView size modifications in there.

I do wonder why this is necessary though as I haven't really had any sluggishness resizing a Window containing WebView - perhaps this is due to your app having different content usage in the WebView from what I have been using.

like image 139
jewelsea Avatar answered Sep 19 '22 00:09

jewelsea


This is not a direct answer to your question. If I understood the sluggishness correctly you are facing somekind weird flashings and renderings. To reduce the sluggishness the size of the webView can be updated manually and more sparsely:

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);
    }
}

The webView is in the Pane which does not layout its children automatically. The webView's size updating is delayed for .5 second ignoring updates in interval.

like image 33
Uluk Biy Avatar answered Sep 17 '22 00:09

Uluk Biy