问题描述
我目前正在从事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.
推荐答案
- 您似乎试图直接从后台线程内进行JavaFX调用,尽管我对JavaFX知之甚少,但我确实知道这是不允许的,必须在JavaFX Application线程上进行JavaFX调用.请参见 JavaFX中的并发性.
- 您甚至都没有创建后台线程.您调用在调用线程上运行的
st.run();
,而不是您想要的.您应该拨打st.start()
! - 作为旁注,您似乎在真正想要实现Runnable的地方扩展了Thread.因此,您确实应该打电话给
new Thread(myRunnable).start();
- 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.
- 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 callingst.start()
! - 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线程冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!