Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

For a JTable I can't create a custum focus traversal policy

843804Aug 25 2004 — edited Apr 14 2005
Hi,

I am really really stuck on this problem can anyone tell me how to create a custom focus traversal policy. When a user presses the tab key I want the first cell in the second column to be selected. when the press the tab key again I want the next cell in the second column to be selected and so on...

I have done all the things that I can see have been suggested on this forum -
1. setting my JTable as the focus traversal root and
2. add focus traversal keys (JTable does not have any)

Only the getDefaultComponent method of my focus traversal policy is being called.
I am also unsure what component I should return - the editor/or renderer or actual cell? At the moment I am just returning the renderer.

Please Help I really can't seem to find the problem!! I attach the code I have tried.
-----------------------------------------------------------------------------------------------------------------------------------------
import java.awt.AWTKeyStroke;
import java.awt.Component;
import java.awt.Container;
import java.awt.FocusTraversalPolicy;
import java.awt.KeyboardFocusManager;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import javax.swing.DefaultListSelectionModel;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn;

public class FocusTableTest extends JFrame{

public JTable table = new JTable();

public FocusTableTest()
{
/** create my table **/
table.setModel(new MyTableModel());
table.setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION);

/**ensure that text components receives the focus when
*they are selected and a key is pressed.
**/
table.setSurrendersFocusOnKeystroke(true);
table.setFocusCycleRoot(true);
MyNewFocusTraversalPolicy policy = new MyNewFocusTraversalPolicy();
table.setFocusTraversalPolicy(policy);
policy.setFocusTraversalKeys(table);

JScrollPane scrollPane = new JScrollPane();
scrollPane.getViewport().setView(table);
this.getContentPane().add(scrollPane);
this.pack();
this.setVisible(true);
}

public static void main(String[] args)
{
new FocusTableTest();
}


/**
* very simple table model just returns a value from a list
*depending on the row that has been selected.
**/
class MyTableModel extends AbstractTableModel
{
List data = new ArrayList();

public MyTableModel()
{
data.add("a");
data.add("b");
data.add("c");
data.add("d");
data.add("e");
data.add("f");
}
public int getRowCount()
{
return data.size();
}

public int getColumnCount()
{
return 2;
}

public String getColumnName(int column)
{
if(column == 0 )
{
return "First Col";
}
else
{
return "Second Col";
}
}

public Object getValueAt(int row, int col)
{
return data.get(row);
}

public boolean isCellEditable(int row, int col)
{
if(col == 1)
{
return true;
}
else
{
return false;
}
}

public void setValueAt(Object value, int row, int col) {

if(col == 1)
{
data.set(row, value);
fireTableCellUpdated(row, col);
}
}
}

/**
* a focus policy which should traverse through the cells in the second column
* only.
*/
class MyNewFocusTraversalPolicy extends FocusTraversalPolicy
{
private int currentSelection = 0;

public MyNewFocusTraversalPolicy()
{
}

/**
* sets the tab key add the focus traversal keys form my JTable.
**/
public void setFocusTraversalKeys(JTable table)
{
AWTKeyStroke tab = AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, 0);
AWTKeyStroke shiftTab = AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, KeyEvent.SHIFT_DOWN_MASK);
AWTKeyStroke ctrlTab = AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, KeyEvent.CTRL_DOWN_MASK);
AWTKeyStroke ctrlShiftTab = AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, KeyEvent.CTRL_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK);

// create a java.util.Set for forwards and backwards focus traversal
// keys. The actual concrete Set you use probably doesn't matter.
// I've used a java.util.HashSet
HashSet forwardKeys = new HashSet();
HashSet backwardKeys = new HashSet();

// add the appropriate keys to the appropriate sets
forwardKeys.add(tab);
forwardKeys.add(ctrlTab);
backwardKeys.add(shiftTab);
backwardKeys.add(ctrlShiftTab);

//set the keys for the this traversal policy.
table.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardKeys);
table.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, backwardKeys);
}

/**
* determines which row is currently selected. returns the renderer
* from the cell below in the second column below it.
*/
public Component getComponentAfter(Container focusCycleRoot,
Component aComponent) {

System.out.println("after");
Component after = null;
int row = table.getSelectedRow();
if(row != -1)
{
if(row+1 < table.getRowCount())
{
after = (Component) table.getCellRenderer(row +1, 1);
}
else
{
after = (Component) table.getCellRenderer(0, 1);
}
}
else
{
after = (Component) table.getCellRenderer(0, 1);
}

return after;
}

public Component getComponentBefore(Container focusCycleRoot,
Component aComponent) {

System.out.println("before");
Component before = null;
int row = table.getSelectedRow();
if(row != -1)
{
if(row-1 >= 0)
{
before = (Component) table.getCellRenderer(row -1, 1);
}
else
{
before = (Component) table.getCellRenderer(table.getRowCount(), 1);
}
}
else
{
before = (Component) table.getCellRenderer(0, 1);
}

return before;
}

public Component getDefaultComponent(Container focusCycleRoot) {

System.out.println("default");
return (Component) table.getCellRenderer(0, 1);
}

public Component getLastComponent(Container focusCycleRoot) {
System.out.println("last");
return (Component) table.getCellRenderer(table.getRowCount(), 1);
}

public Component getFirstComponent(Container focusCycleRoot) {
System.out.println("first");
return (Component) table.getCellRenderer(0, 1);
}
}
}
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on May 12 2005
Added on Aug 25 2004
3 comments
464 views