I have a JavaFx GUI that should be able to show 3D plotly figures. Because the webview of JavaFx doesn't support webgl and therefore can't load plotly 3D plots. So I found JCEF and applyed it to my App.
Here ist the problem:
The following code is to create the gui and display figures using a button.
- Code: Select all
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TestCefWebView extends Application {
private VBox plots = new VBox();
@Override
public void start(Stage primaryStage) throws Exception {
plots.setPadding(new Insets(10));
plots.setSpacing(10);
Button button1 = new Button("Show next plot");
button1.setOnAction(e -> showNextPlot());
plots.getChildren().add(button1);
// Create and define scroll pane to show the plots
ScrollPane scrollPane = new ScrollPane();
scrollPane.setContent(plots);
scrollPane.setVbarPolicy(ScrollBarPolicy.AS_NEEDED);
Scene scene = new Scene(scrollPane, 1200, 800);
primaryStage.setTitle("Plots Test");
primaryStage.setScene(scene);
primaryStage.show();
}
private void showNextPlot() {
// Delete the old figure
plots.getChildren().removeIf(e -> e instanceof SwingNode);
// Load the new figure
CefWebview cefWebview = CefWebview.getInstance();
plots.getChildren().add(cefWebview.load("http://localhost:8090/view/plotlyfigure.html")); // only an example, in reality the url of figure will be changed.
}
public static void main(String[] args) {
launch(args);
System.exit(0);
}
}
Here the CefWebview class:
- Code: Select all
import com.jogamp.opengl.awt.GLJPanel;
import javafx.embed.swing.SwingNode;
import javafx.scene.layout.AnchorPane;
import org.cef.CefApp;
import org.cef.CefClient;
import org.cef.browser.CefBrowser;
public class CefWebview {
private final CefApp app;
private final CefClient client;
private CefBrowser browser;
private static CefWebview instance;
private CefWebview() {
this.app = CefApp.getInstance();
this.client = app.createClient();
}
public static CefWebview getInstance() {
if (CefWebview.instance == null) {
CefWebview.instance = new CefWebview();
}
return CefWebview.instance;
}
public SwingNode load(String url) {
SwingNode swingNode = new SwingNode();
browser = client.createBrowser(url, true, false);
GLJPanel browserUi = (GLJPanel) browser.getUIComponent();
AnchorPane.setTopAnchor(swingNode, 0d);
AnchorPane.setBottomAnchor(swingNode, 0d);
AnchorPane.setRightAnchor(swingNode, 0d);
AnchorPane.setLeftAnchor(swingNode, 0d);
swingNode.setContent(browserUi);
return swingNode;
}
}
When I click the button to show next figure, I want to delete the first page and then show the new page.
But when the old page is deleted, the corresponding jcef_helper.exe process still runs(can be checked in Windows Task Manager). Every time I click the button, a new jcef_helper.exe will be created. That means jcef_helper.exe accumulates. In this way, when the user clicks the button 100 times there will be more than 100 jcef_helper.exe running. That harms on the performance and also takes up much CPU resources.
All of the jcef_helper.exe are killed only if the App is closed.
I've tried client.dispose(), but it birngs no effect.
So is there any way to kill the old jcef_help.exe while App is still alive?
Many thanks!