Sunday, December 28, 2008

Controlling TabIndex in Java Swing

If you have used Visual Basic then you are familiar with TabIndex property. Well some one who moved to Java world recently would think "Where can i set the tab index in Swing applications ?", well the answer is "There is no place to do it."

In Swing tabindex is determined by the layout manager. Layout manager is what layout your GUI's components inside a container such as a JFrame.

So as Swing documentation explains if u want to take control over the tab order in swing you have to implement your own FocusTraversalPolicy. Let see how to do that.

if we check the FocusTraversalPolicy abstract class, there are few abstract methods namely getComponentAfter, getComponentBefore, getFirstComponent, getLastComponent, getDefaultComponent.

We can implement the above methods in such a way that our FocusTraversalPolicy will allow us to give the tab index for our components. So our next problem will be how are we going to record the order of tab index. Well we will be using a component collection which will contains the components where the collection's element order will represent the tab index. The user has to add his/her GUI components into the above collection in the order of tab index he/she needs. The below is part of my implementation.

private class IndexedFocusTraversalPolicy extends 
  FocusTraversalPolicy {

   private ArrayList<Component> components = 
      new ArrayList<Component>();

   public void addIndexedComponent(Component component) {

   public Component getComponentAfter(Container aContainer, 
               Component aComponent) {
        int atIndex = components.indexOf(aComponent);
        int nextIndex = (atIndex + 1) % components.size();
        return components.get(nextIndex);

   public Component getComponentBefore(Container aContainer,
         Component aComponent) {
        int atIndex = components.indexOf(aComponent);
        int nextIndex = (atIndex + components.size() - 1) %
        return components.get(nextIndex);

   public Component getFirstComponent(Container aContainer) {
        return components.get(0);
Put this code inside your JFrame constructor after you have initialized the GUI components.

IndexedFocusTraversalPolicy policy = new IndexedFocusTraversalPolicy();

No matter what layout you use the above GUI's tab order will be as follows.
JtextField1 → jTextField2 → jTextField3 → jTextField4 → jTextField5 → jTextField6
So now you can control your GUI components tab order. :)

Thursday, November 27, 2008

Table Model with Addnew row

Have you ever thought of having your JTable which show a add new row
like in the below screenshot ?

Well you only have to fool the JTable ;) and do some extra stuff in
your model. Below I will how to create the above table model.

In simple if we look at the JTable source we can see it uses
method when it draws table rows. That means
it will draw rows to match the number of rows in your model.
So the first thing you should do is to get a extra row painted
which really not in your model is to override the
method as below.

public final int getRowCount() {
if (dataList == null) {
return 0;
} else {
return dataList.size() + 1;

Note: dataList is the Collection what holding my data in the
model. If your extending the DefaultTableModel, then the
name dataList will be replace by dataVector variable name.

Ok now will the table will draw you a extra row ?
Nope. Because since the last row doesn't exist in my dataList
an ArrayIndexOutOfBoundsException will be thrown from the
model's getValueAt method. So next this is the method we
are going to override. What will do here is we have to take
care of the last row which is not in the dataList. To handle
that will define a method which will return default values for
each column so the TableCellRenderer can render that
value and TableCellEditor will use that value in edit mode.

public Object getColumnDefaultValue(int columnIndex) {
if (columnIndex == 0) {
return "";
} else {
return 0.0;

And the getValueAt method will be modified as below

public final Object getValueAt(int rowIndex, int columnIndex) {
if (rowIndex == dataList.size()) {
return getColumnDefaultValue(columnIndex);
} else {
return super.getValueAt(rowIndex, columnIndex);

Ok now you will see your new row in the JTable. But still you
can't edit, because the setVaueAt method will fail since there
is nothing to edit in the dataList for this new row index.
So we have to override the setValueAt method as well.
What we have to do in this is if the new row index is
edited we have to create a new row in the dataList and
pass the call back the setValueAt in the super class. Here
is the code explaining how to do that.

public final void setValueAt(Object aValue,
int rowIndex, int columnIndex) {
if (rowIndex == dataList.size()) {
super.setValueAt(aValue, rowIndex, columnIndex);

In the above code you can see I have used a method
createNewTableRow. This method take care of the new
row creation. You can find the code below.

public Object[] createNewTableRow() {
return new Object[]{"", 0.0};

Thats all, now you have a TableModel which shows
you new row at the end.