Currently learning play! 2.0, I wanted to add an "opening" to my homepage : the first time a user connects to the homepage, an opening would display for a few seconds and then he would be automatically redirected to the real home page. This opening would not be shown again for the rest of the session.
For now that piece of code looks like :
public class Application extends Controller {
private static ScheduledExecutorService executor = executors.newSingleThreadScheduledExecutor();
public static Result home() {
boolean introSeen = Cache.get("introSeen") == null ? false : true;
if(introSeen) {
System.out.println("Cache good, sending you home !");
return ok(home.render(Configs.HOME));
//return redirect("/");
}
else {
Cache.set("introSeen", true, 2*60*60);
Runnable task = new Runnable(){
#Override
public void run() {
home();
executor.shutdown();
}
};
executor.schedule(task, 7, TimeUnit.SECONDS);
return ok(intro.render(Configs.HOME));
}
}
I've added the println to make sure the cache variable registration and the delayed task were working, and they do. But for an unknown reason, the code
return ok(home.render(Configs.HOME));
is not working and the intro view (intro) stays on screen.
I've tried to user redirect instead of "ok" too, but nothing so far.
Thanks for your help :)
Why don't you just use Meta refresh or some JavaScript technique to do that ?
You can use session cookie for checking if next time user should see the opening or target page.
Related
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.
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.
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 calling st.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();
How can Differentiating browser tab close and refresh functionality.
As of now window refresh and close event doesn't have different events.
My requirement is to checking weather user already logged in or not in any of tabs,So that I wont allow him to load my app in any other tabs.
In GWT (java)
private void registerWindowCloseEvent() {
Window.addCloseHandler(new CloseHandler<Window>() {
#Override
public void onClose(CloseEvent<Window> event) {
// do something on close
}
});
}
in JavaScript/Jquery:
window.onbeforeunload = function(e) {
// do something on close
};
The above events are firing for both the events refresh and close..is there any way to differentiate.
Differentiating browser tab close and refresh functionality is really a pain because we don't have two events to know which event being fired.
But there are always some requirements :)
What I'm doing is setting one cookie in on-load and making a flag true if found that cookie and removing the cookie on browser close event.
So until unless the he closed the active tab(logged in tab), that cookie still there and if he tries to open in another tab, then the already active dialog comes.
Note:Solution provided with help of Cookies.
In
Here is the onModule() for GWT / same as onload/document.ready() for java script/Jquery.
#Override
public void onModuleLoad() {
if("already_in_browser".
equalsIgnoreCase(Cookies.getCookie("already_in_browser"))){
showAlreadyTabActiveDialog();
return;
}else{
setLoggedincookie();
}
private void setLoggedincookie() {
isLoggedintab = true; //this is a global variable
registerWindowCloseEvent();
com.google.gwt.user.client.Cookies.
setCookie("already_in_browser","already_in_browser");
}
private void showAlreadyTabActiveDialog() {
alert("You are already active in another tab");
registerWindowCloseEvent();
}
/** This event is onbeforeunload in javascript
private void registerWindowCloseEvent() {
Window.addCloseHandler(new CloseHandler<Window>() {
#Override
public void onClose(CloseEvent<Window> event) {
if(isLoggedintab ){
Cookies.removeCookie("already_in_browser");
}
}
});
}
Let me know If you found any bugs or loop holes in this.So that I'l look in to them.
I would be very happy,If some one provide a solution,without using cookies.
I have a page crawler developed in Java using Selenium libraries. The crawler goes through a website that launches through Javascript 3 applications which are displayed as HTML in popup windows.
The crawler has no issues when launching 2 of the applications, but on the 3rd one the crawler freezes forever.
The code I'm using is similar to
public void applicationSelect() {
...
//obtain url by parsing tag href attributed
...
this.driver = new HtmlUnitDriver(BrowserVersion.INTERNET_EXPLORER_8);
this.driver.seJavascriptEnabled(true);
this.driver.get(url); //the code does not execute after this point for the 3rd app
...
}
I have also tried clicking on the web element through the following code
public void applicationSelect() {
...
WebElement element = this.driver.findElementByLinkText("linkText");
element.click(); //the code does not execute after this point for the 3rd app
...
}
Clicking on it produces exactly the same result. For the above code, I've made sure I am getting the right element.
Can anyone tell me what could be the problem I'm having?
On the application side, I cannot disclose any information about the html code. I know this makes things harder for trying to solve the problem and for that I apologize in advance.
=== Update 2013-04-10 ===
So, I added the sources to my crawlers and saw where in this.driver.get(url) it was getting stuck on.
Basically, the driver gets lost in an infinite refresh loop. Within a WebClient object instantiated by HtmlUnitDriver, an HtmlPage is loaded which continually refreshes seemingly without end.
Here is the code from WaitingRefreshHandler, which is contained in com.gargoylesoftware.htmlunit:
public void handleRefresh(final Page page, final URL url, final int requestedWait) throws IOException {
int seconds = requestedWait;
if (seconds > maxwait_ && maxwait_ > 0) {
seconds = maxwait_;
}
try {
Thread.sleep(seconds * 1000);
}
catch (final InterruptedException e) {
/* This can happen when the refresh is happening from a navigation that started
* from a setTimeout or setInterval. The navigation will cause all threads to get
* interrupted, including the current thread in this case. It should be safe to
* ignore it since this is the thread now doing the navigation. Eventually we should
* refactor to force all navigation to happen back on the main thread.
*/
if (LOG.isDebugEnabled()) {
LOG.debug("Waiting thread was interrupted. Ignoring interruption to continue navigation.");
}
}
final WebWindow window = page.getEnclosingWindow();
if (window == null) {
return;
}
final WebClient client = window.getWebClient();
client.getPage(window, new WebRequest(url));
}
The instruction "client.getPage(window, new WebRequest(url))" calls WebClient once again to reload the page, only to once more call this very same refresh method. This seems to go on indefinetly, not filling up the memory quickly only because of the "Thread.sleep(seconds * 1000)", which forces a 3m wait before trying again.
Does anyone have any suggestion on how I can work around this issue? I got a suggestion to create 2 new HtmlUnitDriver and WebClient classes which extend the original ones. Then override the relevant methods in order to avoid this problem.
Thanks again.
I solved my eternal refresh problem by creating a do nothing RefreshHandler class:
public class RefreshHandler implements com.gargoylesoftware.htmlunit.RefreshHandler {
public RefreshHandler() { }
public void handleRefresh(final Page page, final URL url, final int secods) { }
}
In addition, I extended the HtmlUnitDriver class and by overriding the method modifyWebClient, I set the new RefreshHandler:
public class HtmlUnitDriverExt extends HtmlUnitDriver {
public HtmlUnitDriverExt(BrowserVersion version) {
super(version);
}
#Override
protected WebClient modifyWebClient(WebClient client) {
client.setRefreshHandler(new RefreshHandler());
return client;
}
}
The method modifyWebClient is a do nothing method created in HtmlUnitDriver exactly for this purpose.
Cheers.
I want to execute only once the action linked to a button even if the user click several times on it.
There is my code :
public String myMethod() {
log.info("Call : myMethod");
if(getLock().tryLock()) {
try {
log.info("Lock");
}
finally {
log.info("unlock");
getLock.unlock();
return null;
}
}
else {
log.info("No permission");
return null;
}
}
My problem :
When I try this, the execution is the following :
Call : myMethod
Lock
Call : myMethod
No permission
unlock
Call : myMethod
Lock
unlock
It seems pretty normal but, all my clicks were made before the first action was done.
So my question is does richfaces has a scheduler and start the action when he wants?
Or someone knows a good way to do this correctly?
Thank you reading
You can use RichFaces queue to "combined" a number of clicks together and only fire one at the end.
We have a ViewerFilter for a TableViewer that is a little slow, so to try to give the impression of awesomeness, we wanted to have the viewer wait 500 milliseconds before refreshing the window (otherwise, it was blocking after every key stroke).
Not having any clue what I was doing, I tried creating a class that would check if System.currentTimeMillis() was greater then the time of the last key stroke + 500 from a different thread. This just caused an Invalid thread access exception to be thrown, so I'm lost.
Edit: I was able to use TableViewer.getTable().getDisplay().asyncExec() to sidestep the invalid thread problem, but I don't like my solution, and would love to hear other suggestions.
You might want to try to turn off redraw while updating the viewer.
Viewer.getControl().setRedraw(false);
// update
Viewer.getControl().setRedraw(true);
It can sometimes give a better user experience. You can also schedule a ui-job that you cancel when the user hits a new key or modifies the text. E.g.
class RefreshJob extends WorkbenchJob
{
public RefreshJob()
{
super("Refresh Job");
setSystem(true); // set to false to show progress to user
}
public IStatus runInUIThread(IProgressMonitor monitor)
{
monitor.beginTask("Refreshing", ProgressMonitor.UNKNOWN);
m_viewer.refresh();
monitor.done();
return Status.OK_STATUS;
};
}
and then reschedule the refresh in a separate job.
private RefreshJob m_refreshJob = new RefreshJob();
private Text m_filterText;
void hookModifyListener()
{
m_filterText.addModifyListener(new ModifyListener()
{
public void modifyText(ModifyEvent e)
{
m_refreshJob.cancel();
m_refreshJob.schedule(500);
}
});
}
If the user hits the Enter key you can schedule a refresh job without the delay,
Just wrap your code in display.syncExec, something like this:
Display.getDefault().asyncExec(new Runnable() {
public void run() {
// check refresh time
// refresh.
}
});
You may want to look in to asyncExec too, if syncExec does not meet your needs.