JDK-5007652 : JComboBox in JTable not closed correctly
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 5.0
  • Priority: P3
  • Status: Closed
  • Resolution: Won't Fix
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2004-03-04
  • Updated: 2004-03-04
  • Resolved: 2004-03-04
Related Reports
Relates :  
Relates :  
Relates :  
Description

Name: gm110360			Date: 03/03/2004


FULL PRODUCT VERSION :
J2SE 1.4.2-b28
J2SE 1.5.0 beta

ADDITIONAL OS VERSION INFORMATION :
Win 2000

A DESCRIPTION OF THE PROBLEM :
Add editable JComboBoxes to a JTable.
Click on arrow button to display pop up for the combobox.
Click on arrow button again to hide the pop up.
Move to a different component in the UI.
The combo box is still displayed with the arrow button still visible.
It should have been removed on a focus lost event.
The combo box is correctly removed if you move to a different cell in the table
rather than a different widget in the application.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Please run the code below: -

1. Click on the drop-down combo-box(under column veggy)
2. Click in "set focus here" textfield.

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

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.Dimension;

public class TableExample3
    implements java.awt.event.ActionListener
{

        ExampleTableModel dataModel;

        final String[] names = {"First Name", "Last Name", "Favorite Color",
                                "Favorite Number", "Veggy"};



        Object[][] data = {
	    {"Mark", "Andrews", "Red", new Integer(2), new Boolean(false)},
	    {"Tom", "Ball", "Blue", new Integer(99), new Boolean(false)},
	    {"Alan", "Chung", "Green", new Integer(838), new Boolean(false)},
	    {"Jeff", "Dinkins", "Turquois", new Integer(8), new Boolean(false)},
	    {"Amy", "Fowler", "Yellow", new Integer(3), new Boolean(false)},
	    {"Brian", "Gerhold", "Green", new Integer(0), new Boolean(false)},
	    {"James", "Gosling", "Pink", new Integer(21), new Boolean(false)},
	    {"David", "Karlton", "Red", new Integer(1), new Boolean(false)},
	    {"Dave", "Kloba", "Yellow", new Integer(14), new Boolean(false)},
	    {"Peter", "Korn", "Purple", new Integer(12), new Boolean(false)},
	    {"Phil", "Milne", "Purple", new Integer(3), new Boolean(false)},
	    {"Dave", "Moore", "Green", new Integer(88), new Boolean(false)},
	    {"Hans", "Muller", "Maroon", new Integer(5), new Boolean(false)},
	    {"Rick", "Levenson", "Blue", new Integer(2), new Boolean(false)},
	    {"Tim", "Prinzing", "Blue", new Integer(22), new Boolean(false)},
	    {"Chester", "Rose", "Black", new Integer(0), new Boolean(false)},
	    {"Ray", "Ryan", "Gray", new Integer(77), new Boolean(false)},
	    {"Georges", "Saab", "Red", new Integer(4), new Boolean(false)},
	    {"Willie", "Walker", "Phthalo Blue", new Integer(4), new Boolean(false)},
	    {"Kathy", "Walrath", "Blue", new Integer(8), new Boolean(false)},
	    {"Arnaud", "Weber", "Green", new Integer(44), new Boolean(false)}
        };

    public TableExample3() {
        JFrame frame = new JFrame("Table");
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {System.exit(0);}});

        // Create a model of the data.
        dataModel = new ExampleTableModel();

        JComboBox _editor = new JComboBox();
        _editor.addItem(new Boolean(false));
        _editor.addItem(new Boolean(true));


        // Instead of making the table display the data as it would normally with:
         JTable tableView = new JTable(dataModel);
        // Add a sorter, by using the following three lines instead of the one above.
        //TableSorter  sorter = new TableSorter(dataModel);
        //JTable    tableView = new JTable(sorter);
        //sorter.addMouseListenerToHeaderInTable(tableView);

        tableView.setDefaultEditor(Boolean.class, new
DefaultCellEditor(_editor));

        JScrollPane scrollpane = new JScrollPane(tableView);

        scrollpane.setPreferredSize(new Dimension(700, 300));

        frame.getContentPane().setLayout(new java.awt.GridBagLayout());
        frame.getContentPane().add(scrollpane);

        JTextField _text = new JTextField("Set focus here");
        frame.getContentPane().add(_text);

        JButton _button = new JButton("Click to remove row");
        frame.getContentPane().add(_button);

        _button.addActionListener(this);

        frame.pack();
        frame.setVisible(true);
    }

    public void actionPerformed(java.awt.event.ActionEvent e)
    {
        dataModel.removeARow();
    }


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


    class ExampleTableModel extends AbstractTableModel
    {
            // These methods always need to be implemented.
            public int getColumnCount() { return names.length; }
            public int getRowCount() { return data.length;}
            public Object getValueAt(int row, int col) {return data[row][col];}

            // The default implementations of these methods in
            // AbstractTableModel would work, but we can refine them.
            public String getColumnName(int column) {return names[column];}
            public Class getColumnClass(int col) {return getValueAt(0,
col).getClass();}
            public boolean isCellEditable(int row, int col) {return true;}
            public void setValueAt(Object aValue, int row, int column) {
                data[row][column] = aValue;
            }

            public void removeARow()
            {
                // Remove last row from array
                Object[][] _smaller_data = new Object[data.length - 1][];
                System.arraycopy(data, 0, _smaller_data, 0,
_smaller_data.length);
                data = _smaller_data;

                System.out.println("Rows = " + data.length);
                System.out.println("Cols = " + data[0].length);


                fireTableDataChanged();
            }
     };
}


REPRODUCIBILITY :
This bug can be reproduced always.
(Incident Review ID: 238317) 
======================================================================

Comments
EVALUATION Name: sh120115 Date: 03/04/2004 It was decided that the behavior of unconditionally cancelling edits was not safe for backward compatibility. Therefore JTable was reversed to do nothing on focus lost by default. Instead a client property was added to control the behavior. Calling the following on the table: table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); will set it up such that on focus lost an attempt will be made to commit the edit. If that fails, the edit will be cancelled. See bugs 4677999, 4709394 and 4724980. Closing as "will not fix". ###@###.### 2004-03-04 ======================================================================
04-03-2004