如何在WebEngine中从javascript调用JavaFX的UI变量?

huangapple go评论86阅读模式
英文:

How to Call to a UI variable of JavaFX from javascript in WebEngine?

问题

我正在开发一个应用程序,需要读取本地文件并在 WebView 中显示,基于用户输入(在 ComboBox 中)。
我试图从 JavaScript 中调用 JavaFX UI 中的变量,但不起作用。

我在 Java 代码中创建了一个名为 getMonthIndex() 的函数,该函数返回 ComboBox 的输入,并且文件应该以适当的名称接收。
我试图将此函数导入 JavaScript 代码中,但似乎未包含在 JavaScript 代码中。

如果您能向我解释如何从 JavaFX UI 获取参数并在 JavaScript 代码中使用它,我将不胜感激。

我的 Controller.java:

public class Controller {

    ObservableList<String> months = FXCollections.observableArrayList
                    ("Tishrei", "Cheshvan", "Kislev", "Tevet", "Shevat", "Adar",
                    "Nisan", "Iyar", "Sivan", "Tammuz", "Av", "Elul");

    public ComboBox<String> month;
    public WebView webView;

    public String getMonthIndex() {
        ReadOnlyIntegerProperty listIndex = month.getSelectionModel().selectedIndexProperty();
        return String.format("%02d", listIndex.getValue());
    }

    public long linesCount(String scanFile) {
        if (scanFile.length() < 80) {
            return scanFile.length() / 15;
        } else {
            return scanFile.length() / 24;
        }
    }

    @FXML
    public void initialize() {
        month.setItems(months);

        webView.setContextMenuEnabled(false);

        WebEngine webEngine = webView.getEngine();
        Controller controller = new Controller();
        JSObject win = (JSObject) webEngine.executeScript("window");
        win.setMember("app", controller);

        month.setOnAction(event -> {
            String loadFile = this.getClass().getResource("index.html").toString();
            webEngine.load(loadFile);
        });
    }
}

我的 index.html(由 WebEngine 上传):

<html>
	<head>
		<meta charset="UTF-8">
		<link rel="stylesheet" type="text/css" href="style.css">
	</head>

	<body onload="readTextFile()">
		<div id="text">
		</div>
		<script type="text/javascript">
			function readTextFile() {
				var xhr, i, text, lines;
				xhr = new XMLHttpRequest();
				xhr.open('GET', app.getMonthIndex()+'.txt', true);
				xhr.send(null);
				xhr.onreadystatechange = function(){
					text = xhr.responseText;
					lines = text.split("\n");
					var allText = "";
					for(i = 0; i < lines.length; i++){
						allText += lines[i]+"<br>";
					}
					document.getElementById("text").innerHTML = allText;
				}
			}
		</script>
	</body>
</html>
英文:

I'm working on an application that needs to read a local file and display it in WebView, based on user input (in ComboBox).
I'm trying to call to a variable in the JavaFX UI from JavaScript and it doesn't work.

I created a function called getMonthIndex() in the Java code that returns the input of the ComboBox and that the file should be received with the appropriate name.
I'm trying to import this function into the JavaScript code, and it doesn't seem to be included in the JavaScript code.

If you can explain to me how to get a parameter from the JavaFX UI and use it within the JavaScript code.

Thanks so much in advance for any help you can.

My Controller.java:

public class Controller {
ObservableList&lt;String&gt; months = FXCollections.observableArrayList
(&quot;Tishrei&quot;, &quot;Cheshvan&quot;, &quot;Kislev&quot;, &quot;Tevet&quot;, &quot;Shevat&quot;, &quot;Adar&quot;,
&quot;Nisan&quot;, &quot;Iyar&quot;, &quot;Sivan&quot;, &quot;Tammuz&quot;, &quot;Av&quot;, &quot;Elul&quot;);
public ComboBox&lt;String&gt; month;
public WebView webView;
public String getMonthIndex() {
ReadOnlyIntegerProperty listIndex = month.getSelectionModel().selectedIndexProperty();
return String.format(&quot;%02d&quot;, listIndex.getValue());
}
public long linesCount(String scanFile) {
if (scanFile.length() &lt; 80) {
return scanFile.length() / 15;
} else {
return scanFile.length() / 24;
}
}
@FXML
public void initialize() {
month.setItems(months);
webView.setContextMenuEnabled(false);
WebEngine webEngine = webView.getEngine();
Controller controller = new Controller();
JSObject win = (JSObject) webEngine.executeScript(&quot;window&quot;);
win.setMember(&quot;app&quot;, controller);
month.setOnAction(event -&gt; {
String loadFile = this.getClass().getResource(&quot;index.html&quot;).toString();
webEngine.load(loadFile);
});
}
}

My index.html (uploaded by WebEngine):

&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;UTF-8&quot;&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;style.css&quot;&gt;
&lt;/head&gt;
&lt;body onload=&quot;readTextFile()&quot;&gt;
&lt;div id=&quot;text&quot;&gt;
&lt;/div&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
function readTextFile() {
var xhr, i, text, lines;
xhr = new XMLHttpRequest();
xhr.open(&#39;GET&#39;, app.getMonthIndex()+&#39;.txt&#39;, true);
xhr.send(null);
xhr.onreadystatechange = function(){
text = xhr.responseText;
lines = text.split(&quot;\n&quot;);
var allText = &quot;&quot;;
for(i = 0; i &lt; lines.length; i++){
allText += lines[i]+&quot;&lt;br&gt;&quot;;
}
document.getElementById(&quot;text&quot;).innerHTML = allText;
}
}
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;

答案1

得分: 1

你正在创建一个新的 Controller 实例,它与 UI 没有任何连接,并将其传递给了 Web 引擎:

Controller controller = new Controller();
JSObject win = (JSObject) webEngine.executeScript("window");
win.setMember("app", controller);

相反,只需传递当前实例:

// Controller controller = new Controller();
JSObject win = (JSObject) webEngine.executeScript("window");
win.setMember("app", this);
英文:

You’re creating a new instance of the Controller, which has no connection at all to the UI, and passing it to the web engine:

    Controller controller = new Controller();
JSObject win = (JSObject) webEngine.executeScript(&quot;window&quot;);
win.setMember(&quot;app&quot;, controller);

Instead, just pass the current instance:

    // Controller controller = new Controller();
JSObject win = (JSObject) webEngine.executeScript(&quot;window&quot;);
win.setMember(&quot;app&quot;, this);

huangapple
  • 本文由 发表于 2020年5月4日 09:36:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/61583890.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定