I am working on a single page wicket application. When ever user clicks on a Navigation Item a new Tab is opened. The requirement was to have two types of Panels one a normal one and another an Auto refresh panel.
I have a TabPanel class which extends from Panel which actually contains all the Tabs and methods to manage tabs like add, remove, set current.
Following is the customer timer that I have added to TabPanel.
private class AutoRefreshTimer extends AbstractAjaxTimerBehavior {
public AutoRefreshTimer(Duration updateInterval) {
super(updateInterval);
}
@Override
protected void onTimer(AjaxRequestTarget target) {
Tab currentTab = getCurrentTab();
if(currentTab != null) {
if(currentTab.getPanel() instanceof AutoRefreshPanel) {
AutoRefreshPanel ajaxRefreshPanel = (AutoRefreshPanel) currentTab.getPanel();
ajaxRefreshPanel.onRefresh(target);
}
}
}
}
Following is the method to added the timer 'autoRefreshTimer' which is an instance variable in TabPanel class.
private void addNewAutoRefreshTimer(final Duration autoRefreshInterval) {
autoRefreshTimer = new AutoRefreshTimer(autoRefreshInterval);
add(autoRefreshTimer);
}
Following are the methods to control the timer:
public void startAutoRefreshTimer(final AjaxRequestTarget target, final Duration autoRefreshInterval) {
if(!autoRefreshTimer.isStopped())
addNewAutoRefreshTimer(autoRefreshInterval);
autoRefreshTimer.restart(target);
}
public void stopAutoRefreshTimer(final AjaxRequestTarget target, final Duration autoRefreshInterval) {
if(autoRefreshTimer.isStopped())
addNewAutoRefreshTimer(autoRefreshInterval);
autoRefreshTimer.stop(target);
}
public void toggleAutoRefreshTimer(final AjaxRequestTarget target){
Tab currentTab = getCurrentTab();
if(currentTab != null) {
if(currentTab.getPanel() instanceof AutoRefreshPanel) {
AutoRefreshPanel ajaxRefreshPanel = (AutoRefreshPanel)currentTab.getPanel();
this.autoRefreshInterval = ajaxRefreshPanel.getAutoRefreshInterval();
startAutoRefreshTimer(target, this.autoRefreshInterval);
return;
}
}
stopAutoRefreshTimer(target, this.autoRefreshInterval);
}
The timer starts and stops in my local server when ever the user switches between the tabs either opening a new, or switch to already opened, close current which selects the previous tab, or close another tab without switching from current. But when I test the same in our staging server which is in a remote location, the timer fails in following scenario.
Following is the step which creates the issue in Remote:
1. Open two Normal tabs.
2. Open a tab containing AutoRefreshPanel.
3. Close 1st or 2nd normal tab by keeping the tab containing AutoRefreshPanel active/current. This expect the timer to be
fired/running.
4. Switch to the remaining Normal tab. This stops the timer in local server but not in Remote.
Apart from the above mentioned step in all other scenarios the timer starts and stops as expected in both local and remote.
// UPDATE: I found a fix for this issue. But not sure is it the best one. Following is the changes that I have made:
private class AutoRefreshTimer extends AbstractAjaxTimerBehavior {
public AutoRefreshTimer(Duration updateInterval) {
super(updateInterval);
}
@Override
protected void onTimer(AjaxRequestTarget target) {
Tab currentTab = getCurrentTab();
if(currentTab != null) {
if(currentTab.getPanel() instanceof AutoRefreshPanel) {
AutoRefreshPanel ajaxRefreshPanel = (AutoRefreshPanel) currentTab.getPanel();
ajaxRefreshPanel.onRefresh(target);
return; // added return
}
}
stop(target); // added a call to stop method.
}
}
// Replaced startAutoRefreshTimer, stopAutoRefreshTimer and toggleAutoRefreshTimer with the following method:
public void manageAutoRefreshTimer(final AjaxRequestTarget target){
Tab currentTab = getCurrentTab();
if(currentTab != null) {
if(currentTab.getPanel() instanceof AutoRefreshPanel) {
AutoRefreshPanel ajaxRefreshPanel = (AutoRefreshPanel)currentTab.getPanel();
this.autoRefreshInterval = ajaxRefreshPanel.getAutoRefreshInterval();
if(!autoRefreshTimer.isStopped())
addNewAutoRefreshTimer(autoRefreshInterval);
autoRefreshTimer.restart(target);
}
}
}