JDK-4871932 : MouseMotionListener on JTable disappears when Look And Feel (LAF) changes
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.3.1_06,1.4.1,1.4.1_02,1.4.2
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2003-05-30
  • Updated: 2003-06-02
  • Resolved: 2003-06-02
Related Reports
Duplicate :  
Description

Name: jk109818			Date: 05/30/2003


FULL PRODUCT VERSION :
java version "1.4.1_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_02-b06)
Java HotSpot(TM) Client VM (build 1.4.1_02-b06, mixed mode)

FULL OS VERSION :
Microsoft Windows 2000 [Version 5.00.2195]

A DESCRIPTION OF THE PROBLEM :
Well, I have a JTable on which I added a Mouse Motion Listener to restrict the selection of rows to a particular column. That means, the user clicks on a particular cell of the JTable and moves his mouse. Only, cells of the same column could be selected, even if the mouse is moved on others columns.
However, the user have the ability to change the look and feel of the application. If he changes teh look and feel, the mouse motion listener has no effects on the jtable. The user can select cells in several columns at the same time.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Steps:
1) launch the application
2) click on a cell of the JTable with the left button of the mouse
3) keep the button pressed and move the mouse to another row and column
-> only the cells of the first column are selected
4) use the "Look and Feel" menu to change the look and feel of the application
5) redo steps 1, 2 and 3
-> all cells from the first selected one to the last one are selected

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The result expected is the same as before to change the look and feel. Only the cells of the same column should be selected even if the user moves his mouse to another column
ACTUAL -
After changing the look and feel, cells in different columns can be selected at the same time

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

/**
 * <p>Titre : </p>
 * <p>Description : </p>
 * <p>Copyright : Copyright (c) 2003</p>
 * <p>Soci��t�� : </p>
 * @author non attribu��
 * @version 1.0
 */
public class MyTable extends JFrame {
  private JTable dataTable;
  private int colIndex;

  public MyTable(){
    super("Table");
    Container contentPane = this.getContentPane();
    contentPane.setLayout(new BorderLayout());

    // -- Create the menus bar --
    this.setJMenuBar(createMenus());

    // -- Create the table --
    Object[][] obj = {{"Mary", "Campione", "Snowboarding", "5", "false"},
                      {"Alison", "Huml", "Rowing", "3", "true"},
                      {"Kathy", "Walrath", "Chasing toddlers", "2", "false"},
                      {"Sharon", "Zakhour", "Speed reading", "20", "true"},
                      {"Angela", "Lih", "Teaching high school", "4", "false"}};

    Object[] cols = {"First Name", "Last Name", "Sport", "# of Years", "Vegetarian"};
    dataTable = new JTable(obj, cols);

    // -- Allow to select several contiguous cells --
    dataTable.setRowSelectionAllowed(true);
    dataTable.setColumnSelectionAllowed(true);
    dataTable.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);

    // -- Listener use to get the column corresponding to the x position of the mouse --
    dataTable.addMouseListener(new MouseAdapter() {
      public void mousePressed(MouseEvent e) {
        colIndex = dataTable.columnAtPoint(e.getPoint());
        dataTable.setColumnSelectionInterval(colIndex, colIndex);
      }
    });

    // -- Listener to select cells in one and only one column --
    dataTable.addMouseMotionListener(new MouseMotionAdapter() {
      public void mouseDragged(MouseEvent e) {
        dataTable.setColumnSelectionInterval(colIndex, colIndex);
        dataTable.repaint();
      }
    });

    // -- Add the table to the panel --
    JScrollPane scroll = new JScrollPane(dataTable);
    contentPane.add(scroll);

    //
    this.pack();
    this.show();
  }

  /*****************************************************************************
   *
   * @return
   */
  public JMenuBar createMenus() {
    JMenuBar menuBar = new JMenuBar();
    JMenu lookMenu = new JMenu("Look & Feel");
    JMenuItem item = new JMenuItem("Windows");
    item.addActionListener(new ActionListener(){
      public void actionPerformed(ActionEvent e) {
        try {
          UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
          SwingUtilities.updateComponentTreeUI(MyTable.this);
        } catch (Exception ex) {}
      }
    });
    lookMenu.add(item);

    item = new JMenuItem("Metal");
    item.addActionListener(new ActionListener(){
      public void actionPerformed(ActionEvent e) {
        try {
          UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
          SwingUtilities.updateComponentTreeUI(MyTable.this);
        } catch (Exception ex) {}
      }
    });
    lookMenu.add(item);
    menuBar.add(lookMenu);
    return menuBar;
  }

  /*****************************************************************************
   *
   * @param args
   */
  public static void main(String[] args){
    /*try {
      UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    } catch (Exception ex) {}*/
    new MyTable();
  }
}
---------- END SOURCE ----------
(Review ID: 186485) 
======================================================================

Comments
EVALUATION The listeners that the submitter's code is adding to JTable are not dissapearing. What is happening is that their order in the component's listener list is changing. The submitter's code relies on their listeners being called after the listeners already installed on the JTable (by the UI class). However, when a UI switch happens, those UI listeners are uninstalled and new ones are installed. The new ones happen to be installed after the listeners installed by the submitter's code. Due to this ordering change, the submitter's listeners no longer have the desired effect. This isn't really a bug since we don't guarantee the order of listener notification. However, there is an open RFE, 4178930, requesting some type of listener ordering API. I am closing this as a duplicate of that bug. ###@###.### 2003-06-02
02-06-2003