使用隧道交互在我的 webview 上重新加载 Html 文件

Reload a Html file on my webview with tunnel interaction

我现在在我的 webview 组件上重新加载 html 文件时遇到问题。

所以,基本上,当我 运行 应用程序时,我的 html 文件在我的程序中运行良好(HTML 文件位于我的本地存储)。

但是当我想重新加载 html 文件时(通过在我的 webview 上执行重新加载操作),我的隧道似乎有问题(我为与另一个 javafx 组件交互而创建的)我的 html 文档有不同的行为,因为它应该有...

package Visual.SintaxDirectedEditor;

import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.StackPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Screen;
import javafx.stage.Stage;
import netscape.javascript.JSObject;
import org.fxmisc.richtext.CodeArea;
import org.fxmisc.richtext.LineNumberFactory;

import java.io.File;

public class Main {
 private Scene scene;
 private Stage stage;
 private final String title = "liss | SDE";
 private final double width = 600;
 private final double height = 400;
 private final double cX = 0.00, cY = 0.00;


public Main() throws Exception {

    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("sde.fxml"));
    AnchorPane page = (AnchorPane) fxmlLoader.load();
    scene = new Scene(page);

    stage = new Stage();
    stage.setScene(scene);
    stage.setTitle(this.title);

    //Maximize the menubar width with parent node
    //MenuBar mb = (MenuBar) scene.lookup("#menuBar");
    //mb.prefWidthProperty().bind(stage.widthProperty());

    //Set minimum width and height of the window
    stage.setMinWidth(width);
    stage.setMinHeight(height);

    //Maximize window
    Screen screen = Screen.getPrimary();
    Rectangle2D bounds = screen.getVisualBounds();

    stage.setX(bounds.getMinX());
    stage.setY(bounds.getMinY());
    stage.setWidth(bounds.getWidth());
    stage.setHeight(bounds.getHeight());

    //Set coordinates of the window
    //stage.setY(cY);
    //stage.setX(cX);


    WebView wv = (WebView) fxmlLoader.getNamespace().get("tree");
    StackPane sp = (StackPane) fxmlLoader.getNamespace().get("code_editor");

    //Add Html file to WebEngine and set the context menu of the HTML file false
    File f = new File("ressources/html/index.html");
    WebEngine we = wv.getEngine();
    we.setJavaScriptEnabled(true);
    we.load(f.toURI().toURL().toString());
    wv.setContextMenuEnabled(false);

    //Add the RichText plugin to JavaFx application
    CodeArea codeArea = new CodeArea();
    codeArea.setParagraphGraphicFactory(LineNumberFactory.get(codeArea));
    codeArea.setEditable(false);
    codeArea.setStyle("-fx-font-size:15;");
    sp.getChildren().add(codeArea);

    //Creating a bridge for WebEngine to Java code application
    JSObject jsobj = (JSObject) we.executeScript("window");
    LissProgram l = new LissProgram(codeArea);
    jsobj.setMember("liss", l);


    //When "close menuitem" is clicked, then it exits the program
    MenuItem closeMenuItem = (MenuItem) fxmlLoader.getNamespace().get("close");
    closeMenuItem.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent e) {
            Platform.exit();
        }
    });

    //When the "new menuitem" is clicked, then it must create
    MenuItem newMenuItem = (MenuItem) fxmlLoader.getNamespace().get("new");
    newMenuItem.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent e) {
            wv.getEngine().reload();
        }
    });


    stage.show();
 }

}

我的代码有什么问题?

好的,所以我终于设法通过向我的网络引擎添加一个功能来解决问题![​​=11=]

通过这样做:

//Creating a bridge for WebEngine to Java code application
    we.documentProperty().addListener((observable, oldValue, newValue) -> {
        //Comment about this piece of code: When a user want to create a new liss file, we must add this piece of code into the function addListener function.
        JSObject jsobj = (JSObject) we.executeScript("window");
        LissProgram l = new LissProgram(codeArea);
        jsobj.setMember("liss", l);
    });

我添加了一个 "addListener" 函数并在那里更改了我的 JSObject。 现在,我的页面重新加载并且 tunnel/bridge 完美运行。 希望对以后的开发者有所帮助。

您使用以下代码行注册了一个网桥:

//Creating a bridge for WebEngine to Java code application
JSObject jsobj = (JSObject) we.executeScript("window");
final LissProgram lissProg = new LissProgram(codeArea);
jsobj.setMember("liss", lissProg);

实际发生的是在全局上下文 (window) 上创建了一个 JavaScript 对象 liss。但是,当您重新加载页面时,全局上下文也会重新加载。因此你必须在重新加载后重新注册liss:

//When the "new menuitem" is clicked, then it must create
MenuItem newMenuItem = (MenuItem) fxmlLoader.getNamespace().get("new");
newMenuItem.setOnAction(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent e) {
        final WebEngine webEngine = wv.getEngine();
        webEngine .reload();
        webEngine.getLoadWorker().stateProperty().addListener(
        new ChangeListener<State>() {
            public void changed(ObservableValue ov, State oldState, State newState) {
                if (newState == State.SUCCEEDED) {
                    JSObject jsobj = (JSObject) we.executeScript("window");
                    jsobj.setMember("liss", lissProg);
                }
            }
        });

    }
});