2015-05-19 56 views
0

此问题可能被认为是对this qeustion的简单扩展我有一个带有标签和WebView的简单应用程序。 WebView包含一个小矩形,其onclick应该调用JavaFX中的方法并更改标签的文本。使用Javascript回调方法更改JavaFX标签

以下是我FXML文件

<?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类是

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。

question的答案,我可以理解FXMLDocumentController可以作为参数传递,但我不知道如何访问控制器,当我通过JavaScript回调访问它。

回答

0

定义在Connector类中的字段和一个构造函数初始化:

public void connecting() { 
    // ... 

    controller.setLabelText("Bye World"); 
    // ... 
} 

就像你想做的事:

public class Connector { 

    private final FXMLDocumentController controller ; 

    public Connector(FXMLDocumentController controller) { 
     this.controller = controller ; 
    } 

    // ... 
} 

然后你就可以直接在connecting()方法引用controller先前。

现在你只需构建Connector与参考控制器:

public class FXMLDocumentController { 

    // ... 

    public void initiateWeb() { 
     // ... 

     webEngine.getLoadWorker().stateProperty().addListener(
      new ChangeListener<State>() { 
       // ... 

       win.setMember("javaObj", new Connector(FXMLDocumentController.this)); 
       // ... 
      } 
     ); 
    } 
    // ... 
} 

由于这一变化,在Java 8中,而不是在Connector类存储控制器的引用,你可能只是存储功能,用于处理所述消息:

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"); 
    } 
}); 
+0

完美的作品:) – Talat