1

Getting the error mentioned as title. Depicting the scenario below (JavaFX 8):

Main.java

public class Main extends Application {
    private Parent rootNode;

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

    @Override
    public void init() throws Exception {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/Main.fxml"));
        rootNode = fxmlLoader.load();
    }

    @Override
    public void start(Stage stage) throws Exception{
        stage.setTitle("Proxy Server");
        stage.setScene(new Scene(rootNode));
        stage.show();
    }
}

I've a controller (MainController.java) for the view Main.fxml.

MainController.java

public class MainController {
    @FXML
    private TextField inputUrl;

    @FXML
    private Button goButton;

    @FXML
    private TextArea outputTextArea;

    @FXML
    private TextField proxyServerAddress;

    @FXML
    private WebView webView;

    @FXML
    private void handleGoButtonAction(ActionEvent event) {
        Window owner = goButton.getScene().getWindow();

        ExecutorService threadPool = Executors.newFixedThreadPool(10);

        StringTokenizer tokenizer = new StringTokenizer(proxyServerAddress.getText(), ":");
        ClientWorker clientWorker = new ClientWorker(this.webView, this.outputTextArea,
                tokenizer.nextToken(),
                Integer.parseInt(tokenizer.nextToken()),
                inputUrl.getText());
        threadPool.execute(clientWorker);
    }
}

From the controller's handleGoButtonAction action event I'm passing the reference of webView. Inside ClientWorker I'm getting the instance of WebEngine from passed reference of webView:

ClientWorker.java

public class ClientWorker implements Runnable {
    @FXML
    private TextArea outputTextArea;

    @FXML
    private WebView webView;

    private Socket socket;
    private String proxyServerUrl;
    private Integer proxyServerPort;
    private String url;

    public ClientWorker(WebView webView, TextArea outputTextArea, String proxyServerUrl, Integer proxyServerPort, String url) {
        this.webView = webView;
        this.outputTextArea = outputTextArea;
        this.proxyServerUrl = proxyServerUrl;
        this.proxyServerPort = proxyServerPort;
        this.url = url;
        try {
            this.socket = new Socket(proxyServerUrl, proxyServerPort);
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }

    public void run() {
        try {
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            out.println(this.url);

            //flushes the stream
            out.flush();

            String feed = null;
            StringBuilder sb = new StringBuilder();
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            //read from socket input stream (responses from server)
            while ((feed = in.readLine()) != null) {
                sb.append(feed);
                sb.append("\n");
            }
            //settings server response to GUI
            outputTextArea.setText(sb.toString());
            WebEngine engine = webView.getEngine();
            engine.loadContent(sb.toString());
            return;
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }
}

For the above scenario I'm getting the java.lang.IllegalStateException: Not on FX application thread; currentThread = JavaFX-Launcher Exception. (contents I'm loading through WebEngine is html in a string)

fatCop
  • 2,218
  • 9
  • 31
  • 50
  • I'm in a different thread. Interesting thing is I can update the textArea but nothing on webView. – fatCop Oct 07 '18 at 22:31
  • 2
    A lot of objects in JavaFX can be created and modified on any thread—so long as they are not part of a live scene-graph. However, there are certain objects that must only be used from the _JavaFX Application Thread_: `Window`, `Scene`, `WebView`, etc. If you read the Javadoc of `WebView` it says, "_`WebView` objects must be created and accessed solely from the FX thread_". In JavaFX, the `Application.init` method is called on the _JavaFX-Launcher_ thread; it's the `Application.start` method that is called on the _JavaFX Application Thread_. – Slaw Oct 07 '18 at 22:51
  • thanks for a legit explanation! @Slaw – fatCop Oct 07 '18 at 22:57
  • Updating from JavaFX thread did the work. Thanks – fatCop Oct 07 '18 at 23:00

0 Answers0