Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4528436

Broken focusHandling when using editable ComboBoxes as cellEditor in JTable

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P3 P3
    • None
    • 1.4.0
    • client-libs



      Name: gm110360 Date: 11/16/2001


      java version "1.4.0-beta3"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta3-b84)
      Java HotSpot(TM) Client VM (build 1.4.0-beta3-b84, mixed mode)


      There are several issues (merlin beta3) (use the attached sample
      to reproduce):


      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


      B: regarding starting of edit


      The little scheme below shows what happens if you try to
      start an edit in a cell with an editable combo (the cell
      is the anchor). First column is what to do, second/third columns
      are with surrenderFocusOnKeystroke set to off/on, respectively.
      Content of these show where the focus is after the user
      gesture in column 1:

      Input | surrender off | surrender on
      ------------------------------------
      F2 | combo | combo
      keytype | no effect | combo
      click | textField | textfield

      Subsequent key types are received by the combo only if the
      editor's textfield has the focus, that is only after a
      mouseClick. If the combo has the focus (you see the editor
      appear, focus seems to be on the button) the textfield does
      not get the input. That's clearly unacceptable: at least F2
      should put the editor into a state where it is able to accept
      subsequent keystrokes.

      The reaction to an arbitrary keytype as edit starter at
      least has to be defined/documented somewhere. I tend to
      treat is similar to a textfield. Again, just showing
      the combo without making it accesible for input is unacceptable.

      Greetings
      Jeanette

      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();
      }
      }
      (Review ID: 135159)
      ======================================================================

            dmcduffisunw Dale Mcduffie (Inactive)
            gmanwanisunw Girish Manwani (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: