JDK-6491619 : No mouse events from titlebar in JRootPane of JFrame
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2006-11-09
  • Updated: 2011-03-08
  • Resolved: 2011-03-08
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 6 JDK 7
6u12Fixed 7 b07Fixed
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0-beta2"
Java(TM) SE Runtime Environment (build 1.6.0-beta2-b86)
Java HotSpot(TM) Client VM (build 1.6.0-beta2-b86, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
I use a JRootPane to capture all mouse events on a certain JFrame (top-level window), using the Java Look & Feel.  In Java 1.4 and 1.5, this works as expected.  With Java 1.6 (Beta 2), my event handler is not being called for mouse events in the titlebar.  This change was probably intentional, but annoying, and I cannot find it documented anywhere.  I tried capturing the mouse events from the glassPane, but that did not work either.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
public class MyClass implements MouseListener, MouseMotionListener
...
JRootPane top_root = ((JFrame)top).getRootPane();
top_root.addMouseListener(this);
top_root.addMouseMotionListener(this);
...
public void mousePressed(MouseEvent e)
...

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The mousePressed, mouseDragged, etc. event handlers in MyClass should be called for all mouse events on the JFrame, including the titlebar.
ACTUAL -
The mousePressed, mouseDragged, etc. event handlers in MyClass are NOT alled for mouse events in the titlebar of the JFrame.

REPRODUCIBILITY :
This bug can be reproduced always.


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

public class bartest extends JFrame implements
     MouseListener, MouseMotionListener
   {
   static final int FRAME_WIDTH  = 640;
   static final int FRAME_HEIGHT = 480;

   static final String metal = 
UIManager.getCrossPlatformLookAndFeelClassName();

   boolean drag_message_shown;

   public static void main(String[] args)
     {
     try
       {
       UIManager.setLookAndFeel(metal);
       }
     catch (Exception e)
       {
       }
     JFrame.setDefaultLookAndFeelDecorated(true);
     JFrame test = new bartest();
     test.show();
     test.requestFocus();
     }

   public bartest()
     {
     super("Title Bar Mouse Test");

     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     getContentPane().setLayout(null);
     setBounds(40, 30, FRAME_WIDTH, FRAME_HEIGHT);
     setMaximizedBounds(new Rectangle(
         Integer.MAX_VALUE, Integer.MAX_VALUE, FRAME_WIDTH, FRAME_HEIGHT));
     setResizable(false);
     JRootPane root = getRootPane();
     root.addMouseListener(this);
     root.addMouseMotionListener(this);
     }

   public void mouseEntered(MouseEvent e)
     {
     }

   public void mousePressed(MouseEvent e)
     {
     Component from = e.getComponent();
     System.out.println("Mouse pressed on: " + from.getClass().getName());
     }

   public void mouseReleased(MouseEvent e)
     {
     drag_message_shown = false;
     }

   public void mouseClicked(MouseEvent e)
     {
     }

   public void mouseExited(MouseEvent e)
     {
     }

   public void mouseMoved(MouseEvent e)
     {
     }

   public void mouseDragged(MouseEvent e)
     {
     if (!drag_message_shown)
       {
       drag_message_shown = true;
       Component from = e.getComponent();
       System.out.println("Mouse dragged on: " + from.getClass().getName());
       }
     }
   }
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
I added five transparent JPanel components to the JRootPane, covering the titlebar (a JPanel to the left of the minimize widget, one to the right of the close widget, one in-between the two widgets, and one each above and below the two widgets).  Fortunately, my JPanel is non-resizable, so these five JPanels cover the titlebar consistently and they *DO* capture the "missing mouse events".

Not a particularly neat solution, in fact it is annoyingly crude, but it works.

Release Regression From : 5.0u9
The above release value was the last known release where this 
bug was not reproducible. Since then there has been a regression.

Comments
EVALUATION I was correct, the developer wanted the ability to disable Swing's move/drag support. Given that adding a MouseListener to the rootpane is so rare, I can't think of a good reason not to backout the fix for 4854950, as such, that's what I'm going to do.
22-11-2006

EVALUATION This is a regression introduced in fixing 4854950. Prior to fixing 4854950, MetalRootPaneUI installed listeners on the window. This proved problematic in so far as if a developer added a mouselistener to the rootpane/titlepane, the user could never drag the window (window mouse listener wouldn't be notified). The fix was to add listeners to the rootpane and titlepane. As a result of this, developers adding a listener to the rootpane never get notified if the user clicks on the titlepane (it's deeper than the rootPane). The only scenario I could see this posing problems is if the developer wanted to handle moving the frame themselves. I'm following up with submitter for more information.
13-11-2006

EVALUATION Regression, introduced by the fix to 4854950.
13-11-2006