JDK-6568959 : JTable behaves differently in an JFrame directly vs in a JInternalFrame
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6
  • Priority: P3
  • Status: Open
  • Resolution: Unresolved
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2007-06-12
  • Updated: 2021-07-13
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_01"
Java(TM) SE Runtime Environment (build 1.6.0_01-b06)
Java HotSpot(TM) Client VM (build 1.6.0_01-b06, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
If I have a JTable, and I set all the columns to use the DefaultCellEditor with the clickCountToStart set to 1 (it defaults to 2), the table works fine if placed on a panel directly within a JFrame. But if it is placed within a JInternalFrame, the focus is all messed up.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Run the test case
2. Click on the JTextField under Label "Field1".
3. Click inside a cell in the JTable below the JTextField.
4. Note that even DefaultCellEditor.setClickCountToStart(1) is used. 
5. Comment line 70 & uncomment line 71 in the test case
6. Repeat 2 & 3 to observe the difference.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.Dimension;
import java.util.Enumeration;
import javax.swing.BoxLayout;
import javax.swing.DefaultCellEditor;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
 
public class TableTest extends JFrame
{
	
	public TableTest()
	{
		addWindowListener(new java.awt.event.WindowAdapter()
		{
			public void windowClosing(java.awt.event.WindowEvent evt)
			{
				System.exit(0);
			}
		});
		
		JPanel panel = new JPanel();
		panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
		
		String[] columnNames = {"First Name",	"Last Name","Sport","# of Years","Vegetarian"};
		Object[][] data= new Object[3][5];
		JTable table = new JTable(data, columnNames);
		table.setSurrendersFocusOnKeystroke(true);
		table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
		
		DefaultCellEditor editor = new DefaultCellEditor(new JTextField());
		
		// ************ change to 2 to make it work smoothly
		editor.setClickCountToStart(1);
		TableColumnModel tcm = table.getColumnModel();
		Enumeration e = tcm.getColumns();
		TableColumn col = null;
		while( e.hasMoreElements() )
		{
			col = (TableColumn) e.nextElement();
			col.setCellEditor(editor);
		}
		
		JScrollPane jScrollPane = new JScrollPane();
		jScrollPane.setViewportView(table);
		
		panel.add(new JLabel("Field 1"));
		panel.add(new JTextField(15));
		panel.add(jScrollPane);
		
		// ************ comment out one or the other of these to see error
		initInteralFrame(panel);
		//initNoInteralFrame(panel);
		
		Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
		setSize(new Dimension(800, 600));
		setLocation((screenSize.width-800)/2,(screenSize.height-600)/2);
	}
	
	private void initInteralFrame(JPanel panel)
	{
		JInternalFrame jif = new JInternalFrame();
		JDesktopPane desktop = new JDesktopPane();
		jif.setVisible(true);
		desktop.add(jif);
		setContentPane(desktop);
		jif.add(panel);
		jif.pack();
	}
	
	private void initNoInteralFrame(JPanel panel)
	{
		getContentPane().add(panel);
	}
	
	/**
	 * @param args the command line arguments
	 */
	public static void main(String args[])
	{
		new TableTest().setVisible(true);
	}
	
}

---------- END SOURCE ----------

Comments
EVALUATION The bug is a regression of 4398733 MouseClicked event not delivered when switched between 2 Internal frames The fix idea was to select Internal Frame if it gets a mouse event. However, there isn't any check if the frame is selected or not. A selected frame can be selected again. It causes focus request by the last Frame's focus owner. For the test case it turns out the button. Table loses focus and cell editor hides. The fix idea is to correct the fix for 4398733. New code should check before frame.setSelected(true) invocation the frame is selected or not. src/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java *** 2299,2312 **** --- 2299,2315 ---- Component component = (Component)object; if (component != null) { Component parent = component; while (parent != null && !(parent instanceof Window)) { if (parent instanceof JInternalFrame) { + JInternalFrame frame = (JInternalFrame)parent; + if (!frame.isSelected()) { // Activate the frame. try { ((JInternalFrame)parent).setSelected(true); } catch (PropertyVetoException e1) { } } + } parent = parent.getParent(); } } } }
04-12-2007

EVALUATION I found that the table can get focus even in the Internal Frame. For this purpose you should click exactly on a cell outline.
20-11-2007

EVALUATION The bug is reproduced on jdk7, jdk6 b65. However there is no bug on jdk1.5.0_11. Consequently, the bug was introduced somewhere in early jdk6.
19-11-2007

EVALUATION I reproduced this bug on JDK 7, KeyboardFocusManager for some reason returns focus to the JTextField for the JInternalFrame test case assigned to JInternalFrame owner
30-10-2007