2013-06-04 3 views
2

Je veux en savoir plus sur JavaFX et j'ai donc essayé de configurer Webview. J'ai copié l'exemple de webview sur le site Web d'Oracle et ajouté la fonctionnalité Upcall. Mais ça ne marche pas. En fait, je n'ai aucune idée de comment déboguer un site Web dans Webview. Voici donc le code java:Upcall Javascript à JavaFX

package boersensim; 

import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.geometry.HPos; 
import javafx.geometry.VPos; 
import javafx.scene.Node; 
import javafx.scene.Scene; 
import javafx.scene.layout.HBox; 
import javafx.scene.layout.Priority; 
import javafx.scene.layout.Region; 
import javafx.scene.paint.Color; 
import javafx.scene.web.WebEngine; 
import javafx.scene.web.WebView; 
import javafx.stage.Stage; 
import netscape.javascript.JSObject; 


public class Main extends Application { 
private Scene scene; 
@Override public void start(Stage stage) { 
    // create the scene 
    stage.setTitle("Web View"); 
    scene = new Scene(new Browser(),750,500, Color.web("#666970")); 
    stage.setScene(scene); 
    //scene.getStylesheets().add("webviewsample/BrowserToolbar.css"); 
    stage.show(); 
} 

public static void main(String[] args){ 
    launch(args); 
} 
} 
class Browser extends Region { 

final WebView browser = new WebView(); 
final WebEngine webEngine = browser.getEngine(); 

public Browser() { 
    //apply the styles 
    getStyleClass().add("browser"); 
    // load the web page 
    webEngine.load("test.html"); 
    //add the web view to the scene 
    getChildren().add(browser); 

    JSObject jsobj = (JSObject) webEngine.executeScript("window"); 
    jsobj.setMember("java", new Bridge()); 
} 
private Node createSpacer() { 
    Region spacer = new Region(); 
    HBox.setHgrow(spacer, Priority.ALWAYS); 
    return spacer; 
} 

@Override protected void layoutChildren() { 
    double w = getWidth(); 
    double h = getHeight(); 
    layoutInArea(browser,0,0,w,h,0, HPos.CENTER, VPos.CENTER); 
} 

@Override protected double computePrefWidth(double height) { 
    return 750; 
} 

@Override protected double computePrefHeight(double width) { 
    return 500; 
} 
} 

class Bridge { 
public void exit() { 
    //Platform.exit(); 
    System.out.print("Hello!UPCALL"); 
} 
} 

Le correpondant HTML est:

Click<a href="#" onclick="java.exit();">here</a>to exit the application 

Lorsque je clique sur le lien, rien ne se passe.

Merci à vous à l'avance, Daniel

Répondre

3

mis Bridge() à la page événement chargée

webEngine.setJavaScriptEnabled(true); 
webEngine.getLoadWorker().stateProperty().addListener(
      new ChangeListener<Worker.State>() { 
       public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) { 
        if (newState == Worker.State.SUCCEEDED) {       
         JSObject jso = (JSObject) webEngine.executeScript("window"); 
         jso.setMember("java", new Bridge()); 
        } 

       } 
      }); 
2

J'ai aussi suivi ce tutoriel (probablement celui utilisé): https://blogs.oracle.com/javafx/entry/communicating_between_javascript_and_javafx

Et trouvé que cela fait planter la JVM. Donc, je l'ai signalé un problème sur la JavaFX JIRA, et je suis la réponse suivante:

Il est une exigence depuis 7u5 que les méthodes appelées de JS soient accessibles dans le sens Java, à savoir> les membres du public des classes publiques. (Ceci est mentionné dans le dernier commentaire à l'article). Dans ce cas de test particulier, Bridge doit être déclaré public.

Le plantage a été corrigé dans JDK8. Maintenant, une exception est levée.

Et cela fonctionne.

+0

Si seulement j'avais vu cette réponse il y a 3 heures! J'ai eu une classe interne statique * sans * le modificateur 'public', et les plantages JVM. Ajouté 'public' à la classe et maintenant cela fonctionne. Je vous remercie! – metasim