使用Javascript回调方法更改JavaFX标签 [英] Changing JavaFX label using Javascript callback method

查看:95
本文介绍了使用Javascript回调方法更改JavaFX标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

该问题可能被视为对

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆