JavaFX Thread freeze

时间秒杀一切 提交于 2021-02-05 10:49:50

问题


I'm currently working on a JavaFX project. On GUI initialization I want to read some infos out of a HTML document using Selenium and FirefoxDriver. Normally I would use a crawler to get the infos but this document is full of JavaScript so I was only able to get to the infos using Selenium (I know, it's really bad).

Now I've got the problem that this process takes up to 15 seconds and I want to show the progress of Selenium on a JavaFX progress bar. So I've set up a Thread doing all the work and trying to update the GUI but the Thread freezes until Selenium is finished.

This is my attempt:

public class SeleniumThread extends Thread
{
    private MainViewController main;

    @Override
    public void run()
    {
        try
        {
            WebDriver driver = new FirefoxDriver();
            driver.get("http://---.jsp");
            main.getMain().getPrimaryStage().toFront();
            main.getPbStart().setProgress(0.1);
            WebElement query = driver.findElement(By.id("user"));
            query.sendKeys(new String[] {"Username"});
            query = driver.findElement(By.id("passwd"));
            query.sendKeys(new String[] {"Password"});
            query.submit();
            driver.get("http://---.jsp");
            main.getPbStart().setProgress(0.2);
            sleep(1000);
            main.getPbStart().setProgress(0.25);
            driver.get("http://---.jsp");
            main.getPbStart().setProgress(0.4);
            sleep(1000);
            main.getPbStart().setProgress(0.45);
            driver.get("---.jsp");
            main.getPbStart().setProgress(0.6);
            sleep(1000);
            main.getPbStart().setProgress(0.65);
            query = driver.findElement(By.cssSelector("button.xyz"));
            query.click();
            sleep(1000);
            main.getPbStart().setProgress(0.85);
            System.out.println(driver.getPageSource());
            driver.quit();
        }
        catch(InterruptedException e)
        {
            // Exception ...
        }

    }

    public MainViewController getMain()
    {
        return main;
    }

    public void setMain(MainViewController main)
    {
        this.main = main;
    }
}

MainViewController

public void startup()
{
    if(main.getCc().getMjUsername() != null &&
            main.getCc().getMjPassword() != null &&
            main.getCc().getMjUsername().length() != 0 &&
            main.getCc().getMjPassword().length() != 0)
    {
        SeleniumThread st = new SeleniumThread();
        st.setMain(this);
        st.setDaemon(true);
        st.run();
    }
}

I've read that I should use a Worker like Task for it, but I have no clue how to implement it. And I need to pass a parameter to this Task, because I need to set my primaryStage to the front and update the progress bar.

I hope you can understand my problem. I'd be grateful for every help.


回答1:


You are trying to update the UI from a different thread. The UI can only be updated from the UI thread. To achieve this, wrap the calls to update the progress:

Platform.runLater(() -> {main.getPbStart().setProgress(0.65);});

This will push the update of the UI into the UI thread.




回答2:


  1. You look to be trying to make JavaFX calls directly from within a background thread, and while I know little about JavaFX, I do know that this is not allowed, that JavaFX calls must be made on the JavaFX Application thread. See Concurrency in JavaFX.
  2. You're not even creating a background thread. You call st.run(); which runs st on the calling thread -- not what you want. You should be calling st.start()!
  3. As a side note, you seem to be extending Thread where you really want to be implementing Runnable. Thus you really should be calling new Thread(myRunnable).start();


来源:https://stackoverflow.com/questions/34089055/javafx-thread-freeze

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!