JDK-4684090 : Tab on editable JComboBox inside JTable transfers focus outside JTable
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.4.0,1.4.1
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic,windows_xp
  • CPU: generic,x86
  • Submitted: 2002-05-13
  • Updated: 2005-03-03
  • Resolved: 2005-03-03
Related Reports
Duplicate :  
Relates :  
Description
This bug was originally submitted as the first part of 4528436 and was closed as a duplicate of RFE 4307147. The submitter and I both believe that this issue is unrelated to that RFE. I am therefore opening this new bug. The original description for that issue is:

A: regarding termination of edit

1. when tabbing out of an editing combo (caret blinking in
its JTextField, does accept key input) focus is transferred to
the next component _outside_ the table. In the example that's the
button if the scrollbar is not visible, it's the ScrollBar if visible
(IMO that's another bug: scrollbars should _never_ be focusOwners).

2. same happens when hitting enter

Code:

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;

import java.awt.event.*;
import java.awt.*;
import java.beans.*;
//import de.kleopatra.support.debugon.*;

/**
 *	Trace focus with editable combo as editor
 */
public class ClickCombo {

	protected JFrame frame ;
	// table vars
	protected final int ROWS = 15;
	protected final int COLUMNS = 3;
	protected DefaultTableModel model;
	protected JTable table;
	
	
	public ClickCombo() {
		frame = new JFrame("ClickCombo");
		frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
		frame.getContentPane().add(buildMainPanel());
		frame.getContentPane().add(buildButtonPanel(),
BorderLayout.SOUTH);
		frame.pack();
	//	frame.setSize(300, 200);
		frame.show();
		installFocusTracer();
	}

//---------------------------tracing focus

  protected void installFocusTracer() {
  	KeyboardFocusManager focusManager = KeyboardFocusManager.
  		getCurrentKeyboardFocusManager();
  	new FocusOwnerTracer(focusManager);
  }
  
  public class FocusOwnerTracer implements PropertyChangeListener {
		public static final String FOCUS_OWNER_PROPERTY = "focusOwner";
		protected KeyboardFocusManager focusManager;
		
		public FocusOwnerTracer(KeyboardFocusManager focusManager) {
			this.focusManager = focusManager;
			startListening();
		}
		
		public void startListening() {
			if (focusManager != null) {
				
focusManager.addPropertyChangeListener(FOCUS_OWNER_PROPERTY, this);
			}
		}
		
		public void stopListening() {
			if (focusManager != null) {
				
focusManager.removePropertyChangeListener(FOCUS_OWNER_PROPERTY, this);
			}
		}
		
		public void propertyChange(PropertyChangeEvent e) {
			Component oldOwner = (Component) e.getOldValue();
			Component newOwner = (Component) e.getNewValue();
			ebug("focusOwner changed: ", "");
			debugClass("  old: ", oldOwner);
			debugClass("  new: ", newOwner);
		}
		
		protected void debugClass(String msg, Object o) {
			ebug(msg, o != null ? o.getClass() : null);
		}
	}

//---------------------------helper
	
	protected void ebug(String text, Object o) {
		System.out.println(text + o);
	}
	
//---------------------------init ui
	 	
	protected JComponent buildMainPanel() {
		JPanel panel = new JPanel();
		panel.setLayout(new BorderLayout());
		initTable();
		JScrollPane scroll = new JScrollPane(table);
		panel.add(scroll);
		return panel;
	}
	
	protected void initTable() {
		table = createTable(ROWS, COLUMNS);
		model = (DefaultTableModel) table.getModel();
		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		initComboEditor(0, true);
	}

	protected void initComboEditor(int col, boolean editable) {
		String[] list = { "one", "two", "three", "four", "five", "six"
};
		JComboBox box = new JComboBox(list);
		// trying to properly get key input if table surrenders focus
/*		 {
			public void requestFocus() {
				ebug("Combo: request focus ","");
				if (isEditable()) {
					
getEditor().getEditorComponent().requestFocus();
				} else {
					super.requestFocus();
				}
			}
		};
*/
		box.setEditable(editable);
	//	setBoxVerifier((box));
		TableCellEditor editor = new DefaultCellEditor(box);
		setColumnEditorAt(editor, col);
	}

	protected void setColumnEditorAt(TableCellEditor editor, int col) {
		table.getColumnModel().getColumn(col).setCellEditor(editor);
	}
		
	protected JComponent buildButtonPanel() {
		JPanel panel = new JPanel();
		final JButton button = new JButton("surrender off");
		button.setMnemonic('s');
		frame.getRootPane().setDefaultButton(button);
		ActionListener action = new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				boolean surrender =
!table.getSurrendersFocusOnKeystroke();
				table.setSurrendersFocusOnKeystroke(surrender);
				if (surrender) {
					button.setText("surrender on");
				} else {
					button.setText("surrender off");
				}
			}
		};
		button.addActionListener(action);
		panel.add(button);
		return panel;
	}
	
//---------------------------factory methods

	protected JTable createTable(int r, int c) {
		JTable table= new JTable(r, c);
		return table;
	}

//---------------------------Main

	public static void main(String[] args) {
//		LFSwitcher.windowsLF();
		new ClickCombo();
	}
}

Comments
EVALUATION This can be addressed once 4719336 has been fixed. ###@###.### 2002-08-12 Name: sh120115 Date: 09/24/2004 This looks like a duplicate of 4887999. ###@###.### 2004-09-24 ====================================================================== Yes, this is a duplicate of 4887999. The described behavior no longer occurs in Mustang. ###@###.### 2005-03-03 17:18:29 GMT
03-03-2005