JDK-6231828 : BasicTableUI.java does not check for isPopupTrigger
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 5.0
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2005-02-22
  • Updated: 2010-04-02
  • Resolved: 2005-09-19
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7Resolved
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.5.0_01"

A DESCRIPTION OF THE PROBLEM :
As stated in MouseEvent.isPopupTrigger:

Note: Popup menus are triggered differently on different systems. Therefore, isPopupTrigger  should be checked in both mousePressed  and mouseReleased  for proper cross-platform functionality.

BasicTableUI however does not check for isPopupTrigger() is either.  On systems where BUTTON2 is not the popup trigger this causes selection to be modified before showing the popup.  For instance on Mac systems where Ctrl+BUTTON1 is used for the popup trigger.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run test case provided in Mac L&F.  This will not happen in other L&F, but is a Swing issue!  This issue is even noted in the MouseEvent.isPopupTrigger as mentioned above.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Selection is not lost/changed when a popup is triggered.
ACTUAL -
Selection changes before the popup is shown due to the mouse event handler in BasicTableUI not checking for isPopupTrigger.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.*;
import java.awt.event.*;
import java.lang.reflect.*;
import javax.swing.*;

public class TableTests {
    private JFrame _frame = new JFrame();
    private JTable _table;
    private JPopupMenu _popup;

    public TableTests() {
        _table = new JTable(new String[][] { { "Row 0" }, { "Row 1" }, { "Row 2" }, { "Row 3" }, { "Row 4" }, { "Row 5" } }, new String[] { "Column 1" } );
        _table.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

        _popup = new JPopupMenu();
        _popup.add(new JMenuItem("Popup Menu Item"));

        _table.addMouseListener(new PopupHandler());

        _frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        _frame.getContentPane().add(_table);
        _frame.pack();
        _frame.setVisible(true);
    }

    /**
     * Simple popup handler used for test3813244.
     **/
    protected class PopupHandler extends MouseAdapter {
        public void mousePressed(MouseEvent ev) {
            maybeShowPopup(ev);
        }

        public void mouseReleased(MouseEvent ev) {
            maybeShowPopup(ev);
        }

        protected void maybeShowPopup(MouseEvent ev) {
            if (ev.isPopupTrigger()) {
                _popup.show(ev.getComponent(), ev.getX(), ev.getY());
            }
        }
    }

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

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Difficult as with the new Handler class a lot of state is kept causing subclasses to instead copy and paste the code rather than subclass.  The method shouldIgnore() needs to be modified, but is used by a multitude of functions in the Handler class which in turn may access more private fields.

  Patch to fix this bug follows:
RCS file: /cvs/repository/java/jdk1_4/src/share/classes/javax/swing/plaf/basic/BasicTableUI.java,v
retrieving revision 1.1.1.5
diff -c -r1.1.1.5 BasicTableUI.java
*** BasicTableUI.java   2004/09/08 22:44:29     1.1.1.5
--- BasicTableUI.java   2005/02/22 20:02:11
***************
*** 876,882 ****
          }
  
        private boolean shouldIgnore(MouseEvent e) {
!           return e.isConsumed() || (!(SwingUtilities.isLeftMouseButton(e) &&
                          table.isEnabled()));
        }
  
--- 876,882 ----
          }
  
        private boolean shouldIgnore(MouseEvent e) {
!           return e.isConsumed() || e.isPopupTrigger() || (!(SwingUtilities.isLeftMouseButton(e) &&
                          table.isEnabled()));
        }
###@###.### 2005-2-22 20:28:42 GMT

Comments
EVALUATION Will address under 4833524.
19-09-2005

EVALUATION This problem likely effects many Swing components and fixing it will require thorough testing on multiple platforms (obviously including the Mac).
02-08-2005

EVALUATION Yes, this certainly sounds reasonable. ###@###.### 2005-2-22 20:36:28 GMT
22-02-2005