使用Javascript回调方法更改JavaFX标签 [英] Changing JavaFX label using Javascript callback method
问题描述
This question might be considered as a simple extension to this qeustionI have a simple application with a label and a WebView. The WebView contains a small rectangle whose onclick should invoke a method in JavaFX and change the text of a label.
以下是我的FXML文件
Following is my FXML file
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.web.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="webviewlabel.FXMLDocumentController">
<children>
<VBox prefHeight="200.0" prefWidth="100.0">
<children>
<Label id="lblSample" fx:id="lblSample" text="Sample Label" />
<WebView fx:id="wvSample" prefHeight="200.0" prefWidth="200.0" />
</children>
</VBox>
</children>
</AnchorPane>
我的FXMLController类是
And my FXMLController class is
public class FXMLDocumentController implements Initializable {
@FXML
private Label lblSample;
@FXML
private WebView wvSample;
private WebEngine webEngine ;
@FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
}
@Override
public void initialize(URL url, ResourceBundle rb) {
// wvSample = new WebView();
initiateWeb();
}
public void initiateWeb() {
webEngine = wvSample.getEngine();
webEngine.getLoadWorker().stateProperty().addListener(
new ChangeListener<Worker.State>() {
public void changed(ObservableValue<? extends Worker.State> p, Worker.State oldState, Worker.State newState) {
if (newState == Worker.State.SUCCEEDED) {
JSObject win = (JSObject) webEngine.executeScript("window");
win.setMember("javaObj", new Connector());
System.out.println("FXMLDocumentController.initialize(): Called");
}
}
}
);
webEngine.loadContent(
"<div style='width: 50; height: 50; background: yellow;' onclick='javaObj.Connecting();' />"
);
}
public void setLabelText(String text)
{
System.out.println("FXMLDocumentController.setLabelText(): Called");
lblSample.setText(text);
}
}
连接器类是
public class Connector {
public void Connecting() {
try {
System.out.println("Connector.Connecting(): Called");
/*
FXMLLoader loader = new FXMLLoader(FXMLDocumentController.class.getResource("FXMLDocument.fxml"));
loader.load();
FXMLDocumentController controller = (FXMLDocumentController) loader.getController();
*/
// controller.setLabelText("Bye World");
} catch (Exception ex) {
Logger.getLogger(Connector.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
在上面的连接器类中,如何获取FXMLController类的处理程序,以便可以访问setLabelText.
In the above connector class, how do I get the handler of FXMLController class so that the setLabelText could be accessed.
摘录自问题,我可以理解FXMLDocumentController可以作为参数传递,但是当我通过JavaScript回调访问它时,我不确定如何访问Controller.
From the answers for the question, I could understand that the FXMLDocumentController could be passed as a parameter but I am not sure how to access the Controller when I am accessing it through javascript callback.
推荐答案
在Connector
类中定义一个字段,并使用构造函数对其进行初始化:
Define a field in the Connector
class and a constructor to initialize it:
public class Connector {
private final FXMLDocumentController controller ;
public Connector(FXMLDocumentController controller) {
this.controller = controller ;
}
// ...
}
然后您可以直接在connecting()
方法中引用controller
:
Then you can reference the controller
directly in the connecting()
method:
public void connecting() {
// ...
controller.setLabelText("Bye World");
// ...
}
就像您以前想做的那样.
just as you wanted to do previously.
现在,您只需使用对控制器的引用来构造Connector
:
Now you just construct the Connector
with the reference to the controller:
public class FXMLDocumentController {
// ...
public void initiateWeb() {
// ...
webEngine.getLoadWorker().stateProperty().addListener(
new ChangeListener<State>() {
// ...
win.setMember("javaObj", new Connector(FXMLDocumentController.this));
// ...
}
);
}
// ...
}
作为对此的一种变体,在Java 8中,您可以只存储用于处理消息的函数,而不是在Connector
类中存储对控制器的引用:
As a variation on this, in Java 8, instead of storing a reference to the controller in the Connector
class, you might just store the function for processing the message:
public class Connector {
private final Consumer<String> messageUpdater ;
public Connector(Consumer<String> messageUpdater) {
this.messageUpdater = messageUpdater ;
}
// ...
public void connecting() {
// ...
messageUpdater.accept("Bye world");
// ...
}
}
然后使用
实例化Connector
webEngine.getLoadWorker().stateProperty().addListener((obs, oldState, newState) -> {
if (newState == Worker.State.SUCCEEDED) {
JSObject win = (JSObject) webEngine.executeScript("window");
win.setMember("javaObj", new Connector(this::setLabelText));
System.out.println("FXMLDocumentController.initialize(): Called");
}
});
这篇关于使用Javascript回调方法更改JavaFX标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!