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

JComboBox in JTable not closed corrected

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 1.4.0
    • 1.0.2, 1.1.7, 1.2.0
    • client-libs
    • beta
    • generic, other, x86
    • other, solaris_2.5.1, windows_nt



      Name: rk38400 Date: 05/15/98


      Using Symantec VC 2.5.
      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.

      This more than a minor annoyance because if I try and remove a row from the table by changing the table model,
      I am unable to remove the row containing the combobox correctly. In fact the user can come back and edit the combo box
      even though there is no longer a corresponding row in the table. This can result in array index out of bounds exceptions
      when the model is accessed.

      I've modified (not very neatly) the TableExample3 from the Swing examples. This allows you to reproduce the problem.

      import com.sun.java.swing.*;
      import com.sun.java.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();
                  }
           };
      }
      (Review ID: 30372)
      ======================================================================

            mdavidsosunw Mark Davidson (Inactive)
            rkarsunw Ralph Kar (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: