Article View: borland.public.jbuilder.java.swing
Article #11566Two TAB's needed to traverse focus to a JTable contained within a JScrollPane
From: Scott Lavender
Date: Thu, 06 May 1999 00:00
Date: Thu, 06 May 1999 00:00
219 lines
8259 bytes
8259 bytes
To All,
This problem occurs when using the TAB key to traverse focus
between Swing components. If one of the components is a JTable
contained within a JScrollPane, then it takes two(2) TAB's to
get focus on the JTable.
I did discover that if the JTable is placed into a JPanel first,
and then placed into the JScrollPane, it works with a single TAB.
The following test class demonstrates this problem.
Test 1: using JTable in a JScrollPane FAILS(or demonstrates problem)
Test 2: with JTable in a JPanel and then a JScrollPane works fine
// Begin TabTestPanel Class
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import java.util.*;
public class TabTestPanel extends JPanel
{
JScrollPane scrollPane = null;
JTextField field = new JTextField( 10 );
JTable table = null;
JPanel innerPanel = null;
// Listeners for use by all components
KeyListener keyListener = new KeyEventHandler();
FocusListener focusListener = new FocusEventHandler();
/** * Creates a new instance. */ public TabTestPanel() { // Setup a
JTable TableModel dataModel = new AbstractTableModel() { public int
getColumnCount() { return 5; } public int getRowCount() { return 4;} public
Object getValueAt(int row, int col) { return new String( row + ", " + col );
} }; table = new JTable( dataModel );
/* * Add JComponent to JScrollPane * * NOTE: First select JComponent to
test by uncommenting it's line below. * * Test 1: This test consists of
JComponents placed directly * into a JScrollPane. * * Test 2: This test
consists of JComponents contained in a JPanel * and then added to a
JScrollPane. * * NOTE: For the following tests, comment out comment marks
* for the test to perform. Then uncomment the comment marks for * the test
to disable. */
String test = new String( "Test" );
/*
* Jcomponents to test.
*
* Uncomment the particular component to test. One and only one
* Jcomponent should be uncommented at a time.
*
*/
// Focus,Highlight
//YES, YES JTextField jComponent = new JTextField( test, 10 );
//YES, NO JTree jComponent = new JTree();
// NO, NO
JTable jComponent = table;
//YES, NO JList jComponent = new JList();
//YES, YES JComboBox jComponent = new JComboBox();
//YES, YES JTextArea jComponent = new JTextArea( test, 4, 20 );
//YES, YES JCheckBox jComponent = new JCheckBox( test );
//YES, YES JButton jComponent = new JButton( test );
// Test 1: ScrollPane->JComponent
///*
scrollPane = new JScrollPane( jComponent );
//*/
// Test 2: ScrollPane->JPanel->JComponent
// WORKS!!!
/*
innerPanel = new JPanel();
innerPanel.add( jComponent );
innerPanel.addFocusListener( focusListener );
scrollPane = new JScrollPane( innerPanel );
*/
// Assign FocusListener and KeyListener to Jcomponent and it's parents
jComponent.addFocusListener( focusListener ); jComponent.addKeyListener(
keyListener );
System.out.println( "\nParents of " + jComponent.getClass().getName() );
Enumeration parents = getParentsOfJComponent( jComponent );
while( parents.hasMoreElements() )
{
JComponent parent = (JComponent)parents.nextElement();
System.out.println( "\t" + parent.getClass().getName() );
parent.addFocusListener( focusListener );
parent.addKeyListener( keyListener );
}
System.out.println( "\n" );
// Assign FocusListener and KeyListener to other components
field.addFocusListener( focusListener );
field.addKeyListener( keyListener );
scrollPane.addFocusListener( focusListener );
scrollPane.addKeyListener( keyListener );
scrollPane.getViewport().addFocusListener( focusListener );
scrollPane.getViewport().addKeyListener( keyListener );
// Assign FocusListener and KeyListener to this JPanel
addFocusListener( focusListener );
addKeyListener( keyListener );
// Add JTextField and JScrollPane to JPanel
add( field );
add( scrollPane );
}
private Enumeration getParentsOfJComponent( JComponent jComponent )
{
if( jComponent == null )
return null;
Vector parents = new Vector();
for( Component parent = jComponent.getParent(); parent != null; parent =
parent.getParent() ) parents.add( parent );
return parents.elements();
}
// // Begin - Inner classes // /** * Class to handle key events. */
private class KeyEventHandler extends KeyAdapter { /** * Invoked when a
key has been pressed. */ public void keyPressed(KeyEvent e) { if(
e.getKeyCode() == KeyEvent.VK_TAB ) { if( e.isControlDown() )
System.out.println( "TabTestPanel:KeyEventHandler.keyPressed CTRL-TAB pressed
in " +
((JComponent)e.getComponent()).getClass().getName() ); else
System.out.println( "TabTestPanel:KeyEventHandler.keyPressed TAB pressed in "
+
((JComponent)e.getComponent()).getClass().getName() ); } else
System.out.println( "TabTestPanel:KeyEventHandler.keyPressed " +
e.getKeyText( e.getKeyCode() ) + " pressed in " +
((JComponent)e.getComponent()).getClass().getName() ); }
}
/** * Class to handle focus events. */ private class FocusEventHandler
extends FocusAdapter { /** * Invoked when a component gains the keyboard
focus. */ public void focusGained(FocusEvent e) { System.out.println(
"TabTestPanel:FocusEventHandler.focusGained for " +
((JComponent)e.getComponent()).getClass().getName() );
}
/** * Invoked when a component loses the keyboard focus. */ public void
focusLost(FocusEvent e) { System.out.println(
"TabTestPanel:FocusEventHandler.focusLost for " +
((JComponent)e.getComponent()).getClass().getName() );
}
}
//
// End - Inner classes
//
/**
* Test code.
*
* @param args String array of command line arguments.
*/
public static void main( String[] args )
{
// String lafClassName =
"com.sun.java.swing.plaf.motif.MotifLookAndFeel";
String lafClassName =
"com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
// String lafClassName = "javax.swing.plaf.metal.MetalLookAndFeel";
// String lafClassName = "com.sun.java.swing.plaf.mac.MacLookAndFeel";
try
{
UIManager.setLookAndFeel( lafClassName );
}
catch( Exception ex )
{
ex.printStackTrace();
}
JFrame frame = new JFrame( "Test - " + lafClassName );
frame.getContentPane().add( new TabTestPanel() );
frame.pack();
frame.setVisible( true );
}
}
// End of TabTestPanel Class
Thanks.....
Scott Lavender
ICC/GR Software
100 Deerfield Point
12725 Morris Road, Suite 300
Alpharetta, GA 30004
----------------------------------
Voice: 770-610-4166
Fax: 770-475-5126
Email: lavenders@genrad.com
----------------------------------
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
Technical Details
Message-ID:
<7gsr2s$fm3$1@nnrp1.deja.com>Path:
arc1-ca.pugleaf.net!unknown!not-for-mailShow Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 111d45,5a84cf1faf24ea1b,start X-Google-Attributes: gid111d45,public From: Scott Lavender <scott.lavender@att.net> Subject: Two TAB's needed to traverse focus to a JTable contained within a JScrollPane Date: 1999/05/06 Message-ID: <7gsr2s$fm3$1@nnrp1.deja.com> X-Deja-AN: 474843933 X-Http-Proxy: 1.0 x9.dejanews.com:80 (Squid/1.1.22) for client 198.182.182.73 Organization: Deja News - The Leader in Internet Discussion X-Article-Creation-Date: Thu May 06 19:38:05 1999 GMT Newsgroups: borland.public.jbuilder.java.swing X-Http-User-Agent: Mozilla/4.5 [en] (WinNT; I)