本文介绍了JavaFX线程冻结的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在从事JavaFX项目.在GUI初始化上,我想使用Selenium和FirefoxDriver从HTML文档中读取一些信息.通常我会使用搜寻器来获取信息,但是此文档中充满了JavaScript,因此我只能使用Selenium来获取信息(我知道,这确实很糟糕).

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).

现在,我有一个问题,该过程最多需要15秒,我想在JavaFX进度条上显示Selenium的进度.因此,我设置了一个线程来完成所有工作并尝试更新GUI,但是该线程会冻结直到Selenium完成.

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.

这是我的尝试:

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

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();
    }
}

我已经读到我应该使用像Task这样的Worker,但是我不知道如何实现它.而且我需要向此任务传递参数,因为我需要将primaryStage设置在最前面并更新进度条.

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. 您似乎试图直接从后台线程内进行JavaFX调用,尽管我对JavaFX知之甚少,但我确实知道这是不允许的,必须在JavaFX Application线程上进行JavaFX调用.请参见 JavaFX中的并发性.
  2. 您甚至都没有创建后台线程.您调用在调用线程上运行的st.run();,而不是您想要的.您应该拨打 st.start()
  3. 作为旁注,您似乎在真正想要实现Runnable的地方扩展了Thread.因此,您确实应该打电话给new Thread(myRunnable).start();
  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();

这篇关于JavaFX线程冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 06:12