I want to zoom and de-zoom on a JavaFX application that displays a page with a SVG in it (cf. what is inside String content
). The problem is that there is a viewbox
in the svg part. And when I zoom & de-zoom, only the "Hello World" part zooms & de-zooms, not the svg part (here a black rectangle).
I wish I could just remove the viewbox
, but the user imports their own svg. And I'm not familiar with svgs. Can I just use a regular expression to remove the viewbox part in the code? I wouldn't like to do that (only as a last resort), so is there any way to keep the svg part intact and still having a proper zooming / de-zooming behaviour? Would that be a problem (side-effects I might not anticipate?)?
Here is a minimal reproducible example of my problem:
package com.example.helloworldjavafx;
import javafx.beans.value.ChangeListener;
import javafx.application.Application;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.Tab;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.scene.web.WebEngine;
import static javafx.concurrent.Worker.State;
public class FxWebViewExample1 extends Application
{
public static void main(String[] args)
{
Application.launch(args);
}
@Override
public void start(final Stage stage)
{
// Create the WebView
WebView webView = new WebView();
// Create the Tab and the scrollPane inside it
Tab drawTab = new Tab("Draw");
ScrollPane scrollPane = new ScrollPane();
scrollPane.setContent(webView);
drawTab.setContent(scrollPane);
drawTab.setClosable(false);
// Create the WebEngine
final WebEngine webEngine = webView.getEngine();
// Load the Start-Page
String content = "<html>" +
"<body style='margin: 0'><?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<svg viewBox=\"0 0 115 5\" xmlns=\"http://www.w3.org/2000/svg\">\n" +
"<rect x=\"0\" y=\"0\" width=\"20%\" height=\"20%\"/>" +
"</svg>\n" +
"hello world" +
"</body>\n" +
"</html>\n";
webEngine.loadContent(content);
// Add Zoom management
webView.addEventFilter(ScrollEvent.SCROLL, (ScrollEvent e) -> {
if (e.isControlDown()) {
System.out.println("oui!");
double deltaY = e.getDeltaY();
double zoom = webView.getZoom();
if (deltaY < 0) {
zoom /= 1.1;
} else if (deltaY > 0) {
zoom *= 1.1;
}
webView.setZoom(zoom);
e.consume();
}
});
// Update the stage title when a new web page title is available
webEngine.getLoadWorker().stateProperty().addListener(
new ChangeListener<Worker.State>() {
public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) {
if (newState == Worker.State.SUCCEEDED) {
System.out.println("loading succeeded");
stage.setTitle(webEngine.getTitle());
}
}
});
// Create the VBox
VBox root = new VBox();
// Add the WebView to the VBox
root.getChildren().add(webView);
// Set the Style-properties of the VBox
root.setStyle("-fx-padding: 10;" +
"-fx-border-style: solid inside;" +
"-fx-border-width: 2;" +
"-fx-border-insets: 5;" +
"-fx-border-radius: 5;" +
"-fx-border-color: blue;");
// Create the Scene
Scene scene = new Scene(root);
// Add the Scene to the Stage
stage.setScene(scene);
// Display the Stage
stage.show();
}
}