2

I can successfully open a WebView displaying an html document/url by itself using JavaFX WebEngine and WebView, but I want to open a WebView inside an FXML documents along with other elements such as buttons and ImageView. My goal is to have a GUI which displays images with a html document displaying inside a WebView object.

Here is the program that opens a WebView by itself:

public class HTMLViewer extends Application {

    private Scene scene;
    MyBrowser myBrowser;
    TextArea myTextArea;


public static void main(String[] args) throws IOException, BadLocationException {

    launch(args);
}

    @Override
    public void start(Stage primaryStage) {
    primaryStage.setTitle("HTMLViewer");

    myBrowser = new MyBrowser();
    scene = new Scene(myBrowser, 800, 600);

    primaryStage.setScene(scene);
    primaryStage.show();
}

class MyBrowser extends Region{

    final String hellohtml = "chang.htm"; //html file to view

    WebView webView = new WebView();
    WebEngine webEngine = webView.getEngine();

    public MyBrowser(){

        URL urlHello = getClass().getResource(hellohtml); 
        webEngine.load(urlHello.toExternalForm());

        getChildren().add(webView);
    }
  }    
}

And here is my attempt and loading a WebView through an FXML document which requires a WebView.java main class, WebViewController.java, and WebView.fxml

WebView.java

public class WebView extends Application {
private Object primaryStage;

public static void main(String[] args) {
    launch(args);
}

@Override
public void start(Stage primaryStage) throws IOException {
    Parent root =    FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
    primaryStage.setTitle("HTMLViewer");
    Scene scene = new Scene(root);

    primaryStage.setScene(scene);
    primaryStage.show();
}



WebEngine getEngine() {
    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

}

WebViewController.java

public class FXMLDocumentController implements Initializable {

@FXML
private Label label;
//WebView mywebview = new WebView();
String link = "https://www.google.com";
WebEngine engine;

@FXML
private void handleButtonAction(ActionEvent event) {
    System.out.println("You clicked me!");
    label.setText("Hello World!");
}

@FXML WebView mywebview; //access WebView in FXML document
public void displayWeb() {
    WebEngine engine = mywebview.getEngine();
    final String hellohtml = "chang.htm"; //HTML file to view in web view

    URL urlHello = getClass().getResource(hellohtml);
    engine.load(urlHello.toExternalForm());
}

@Override
public void initialize(URL url, ResourceBundle rb) {
    engine = mywebview.getEngine();
    engine.load(link);
    displayWeb();
}    

}

WebView.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="600.0" prefWidth="900.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="webview.FXMLDocumentController">
    <children>
        <Button fx:id="button" layoutX="23.0" layoutY="24.0" onAction="#handleButtonAction" text="Click Me!" />
        <Label fx:id="label" layoutX="126" layoutY="120" minHeight="16" minWidth="69" />
      <WebView fx:id="mywebview" layoutX="102.0" layoutY="20.0" prefHeight="559.0" prefWidth="775.0" />
    </children>
</AnchorPane>

I get an exception while running the application

Can not set webview.WebView field webview.WebViewController.mywebview to javafx.scene.web.WebView

Is my goal possible to achieve? If so Does anyone know a way to do so? Any help I will be grateful for, thanks.

Maxwell
  • 85
  • 2
  • 3
  • 7
  • 1
    Your custom WebView and the WebView in FXML share the same name, but they are completely different classes. – Prometheus Mar 29 '15 at 03:08
  • @Prometheus Thank you for your comment, I think the classes should still be able to interact with each other because I have done the exact same thing before but with a TextArea instead of a WebView. My main focus is the controller class. I think I asked the question better here: http://stackoverflow.com/questions/29353547/javafx-edit-webview-in-fxml-document – Maxwell Mar 30 '15 at 18:33

2 Answers2

7

A WebView works like any other control when it comes to loading it into a controller from FXML. Below is a minimal example program that displays a website.

Main.java

package webview;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application
{
    @Override
    public void start(Stage primaryStage) throws Exception
    {
        Parent root = FXMLLoader.load(getClass().getResource("WebView.fxml"));
        Scene scene = new Scene(root, 600, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args)
    {
        launch();
    }
}

WebViewController.java

package webview;

import javafx.fxml.FXML;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;

public class WebViewController
{
    @FXML
    private WebView webView;

    @FXML
    private void initialize()
    {
        WebEngine engine = webView.getEngine();
        engine.load("http://www.example.org");
    }
}

I'm not using the Initializable interface here, because it is somewhat obsolete in JavaFX 8.

This interface has been superseded by automatic injection of location and resources properties into the controller. FXMLLoader will now automatically call any suitably annotated no-arg initialize() method defined by the controller. It is recommended that the injection approach be used whenever possible.

WebView.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.web.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="webview.WebViewController">
   <children>
      <WebView fx:id="webView" layoutX="100.0" layoutY="176.0" prefHeight="400.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
   </children>
</AnchorPane>

Why is this not working in your controller? Because you imported the wrong WebView. In the controller, the webView variable is an instance of your custom webview.WebView class, which extends Application and is not a control. The FXMLLoader is trying to assign the javafx.scene.web.WebView from the FXML file and fails, because the types are not compatible.

Prometheus
  • 1,005
  • 6
  • 16
  • This isn't working for me, my webView is just a blank box after running the project. Any help? – dyllandry Jul 05 '16 at 19:57
  • This isn't working because you are trying to load https site. Following link may help you. http://stackoverflow.com/questions/22605701/javafx-webview-not-working-using-a-untrusted-ssl-certificate – Gaurab Pradhan Nov 19 '16 at 09:31
1

This is my Project:

Note : com.example.map

enter image description here

In HelloController :

package com.example.map;

import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;

import java.net.URL;
import java.util.ResourceBundle;
public class HelloController  implements Initializable {
    @FXML
    private WebView view;
    private String link = "http://google.com";
    private WebEngine engine;
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        engine = view.getEngine();
        engine.load(link);
    }
}

In HelloApplication

package com.example.map;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;

public class HelloApplication extends Application {
    @Override
    public void start(Stage stage) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
        Scene scene = new Scene(fxmlLoader.load(), 320, 240);
        stage.setTitle("Hello!");
        stage.setScene(scene);
        stage.show();
    }
    public static void main(String[] args) {
        launch();
    }
}

In hello-view.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<?import javafx.scene.web.WebView?>

<?import javafx.scene.web.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.map.HelloController">
    <children>
        <WebView fx:id="view" layoutX="100.0" layoutY="176.0" prefHeight="400.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
    </children>
</AnchorPane>

Note :

fx:controller="com.example.map.HelloController"

in above code Use correct package name.

If you use Offline html file like : index.html use this line code :

private String link = getClass().getResource("index.html").toExternalForm();

m-tech
  • 338
  • 2
  • 14