We will come across many scenarios in which we may require to do some validation before we proceed from the current tab. In such scenarios, the user should be allowed to proceed only based on the validation outcome.
We don't have a ready made solution for achieving the above outcome. We will discuss here the solution to achieve the above outcome.
During a tab selection in swing JTabbedPane, the javax.swing.JTabbedPane#setSelectedIndex(int) always gets called. So, we will override this method to configure our listener/actions accordingly.
The sample code for achieving this is as follows:
package com.prasune.swing;
import
java.util.ArrayList;
import java.util.List;
import
javax.swing.JTabbedPane;
/**
* This class is a custom tabbed pane
extended from basic JTabbedPane swing
* component.<br>
* The basic JTabbedPane swing component in
Java does not have a pre tab
* selection listener.<br>
* The tab selection in JTabbedPane swing
component happens with the call of
* method {@link #setSelectedIndex(int)}. <br>
* Hence, for plugging in pre tab
selection actions we are overriding
* {@link #setSelectedIndex(int)}
*/
public class CustomTabbedPane
extends JTabbedPane
{
/**
* The index of the tab which the user is
trying to select.
*/
private int currentTargetIndex;
/**
* The Listeners to be fired before tab
changing action.
*/
private List<TabChangeListener> tabChangeListeners = new
ArrayList<TabChangeListener>();
/**
* Constructor made private to ensure
that the instance creation happens via
* call to {@link #createInstance(String)}.
*/
private CustomTabbedPane()
{
}
/**
* This method ensures that component
name will be associated with the
* instance after creation. Component
name help in writing automated test
* cases.
*
* @param name
* The component name to be
associated with instance.
* @return instance of CustomTabbedPane.
*/
public static CustomTabbedPane
createInstance(String name)
{
CustomTabbedPane tabbedPane = new
CustomTabbedPane();
tabbedPane.setName(name);
return tabbedPane;
}
/**
* This method gets called when we select
a tab. This method is overridden
* to plug in pre tab selection
actions which we require to execute.
*
* @param targetIndex
* The index of tab which user is
trying to select.
*/
@Override
public void setSelectedIndex(int targetIndex)
{
if (targetIndex >=
0 && targetIndex < getTabCount())
{
this.currentTargetIndex = targetIndex;
// This check is required for
exceptions during tab creation.
if
(getSelectedIndex() == -1)
{
super.setSelectedIndex(targetIndex);
}
else
{
boolean
continueTabSelectionFlag = false;
// Add your
listener execution here, update
//
continueTabSelectionFlag based on boolean returned by custom
// listener
execution.
for (TabChangeListener
tabChangeListener : tabChangeListeners)
{
continueTabSelectionFlag
= tabChangeListener.execute(this);
if (!continueTabSelectionFlag){
break;
}
}
if
(continueTabSelectionFlag)
{
super.setSelectedIndex(targetIndex);
}
}
}
}
/**
* @return the index of the tab which the
user is trying to select.
*/
public int
getCurrentTargetIndex()
{
return currentTargetIndex;
}
/**
* Add your custom listener instance via
this method.
*/
public void
addTabChangingListeners(
final TabChangeListener
tabChangeListener)
{
tabChangeListeners.add(tabChangeListener);
}
}
|
Our Tab change listener could be something as follows:
package com.prasune.swing;
public class TabChangeListener
{
public boolean
execute(CustomTabbedPane tabbedPane){
// This is required to identify current
index as during
// listener callback index is not yet
set.
int currentTabIndex
= tabbedPane.getCurrentTargetIndex();
// do necessary validations on tabbed
pane and return flag accordingly
return true;
}
}
|