JMenuItem vs glass pane.
Need help figuring out why JMenuItems are not cooperating with the glass pane.
The code below drops the top level menu, however once the list of menu items is displayed, it doesn't respond to any mouse events: moving the mice over doesn't highlight menu items, as it normally does, clicking on any of the items doesn't trigger the corresponding code.
The glass pane is just a transparent JPanel and works fine when mice is over JFrame's content pane.
The code looks at glass pane point coordinates and has a special case if y is less then zero - mice is over the menu bar. This part works fine and the menu items are dropped and displayed after a click on the top level menu. If mice hovers over these - y coordinates are not less then zero anymore, but getDeepestComponentAt() doesn't seem to produce JMenuItem.
Can someone help me with this? Bunch of code out there looks just like it and I can't figure out what's wrong. Thanks for any help.
Here is the redispatching code registered with glass pane mouse and motion listeners:
private void
redespatch( MouseEvent me )
{
// This is the point in glass pane coordinates.
Pointgpp = me.getPoint();
// This holds container: JFrame's content pane or JMenuBar.
Containerc = MyClass.this.getContentPane();
// This is the point in container's coordinates.
Pointcp = SwingUtilities.convertPoint( myGlassPane, gpp, c );
if ( cp.y < 0 )
{
c = mnbrMain; // Main menu bar, JMenuBar.
cp = SwingUtilities.convertPoint( myGlassPane, gpp, c );
}
// This is the redispatching target component.
Componentrtc = SwingUtilities.getDeepestComponentAt( c, cp.x, cp.y );
if ( rtc == null )
{
return;
}
// This is the point in this component's coordinates.
PointcompPoint = SwingUtilities.convertPoint( myGlassPane, gpp, rtc );
// Send this mouse event on it's way.
rtc.dispatchEvent( new MouseEvent(
rtc,
me.getID(),
me.getWhen(),
me.getModifiers(),
compPoint.x,
compPoint.y,
me.getClickCount(),
me.isPopupTrigger() ) );
}
[2202 byte] By [
andronovRa] at [2007-10-3 8:42:08]

Ok, here it is. Built in NetBeans 5.0 on XP.
Tested on XP and Sun Solaris 10 on Sun Blade 1500.
To experiment with problem comment out glassPane.setVisible( true ):
package glasspane;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.event.MouseInputAdapter;
public class GlassPane extends JFrame
{
private JMenuBarmnbrMain = new JMenuBar();
private JMenumnuFile = new JMenu();
private JMenuItemmniOpen = new JMenuItem();
private JMenuItemmniSave = new JMenuItem();
private JMenuItemmniClose = new JMenuItem();
private JMenuItemmniExit = new JMenuItem();
private JPanelpnlMain = new JPanel();
private JButtonbtnBig = new JButton( "Big one" );
private MyGlassPaneglassPane = new MyGlassPane();
public GlassPane()
{
setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE );
setTitle( "JMenuItem vs glass pane" );
setJMenuBar( mnbrMain ); mnbrMain.add( mnuFile ); mnuFile.setText( "File" );
mnuFile.add( mniOpen ); mniOpen.setText( "Open" );
mnuFile.add( mniSave ); mniSave.setText( "Save" );
mnuFile.add( mniClose ); mniClose.setText( "Close" );
mnuFile.add( mniExit ); mniExit.setText( "Exit" );
getContentPane().add( pnlMain );
pnlMain.add( btnBig );
btnBig.setPreferredSize( new Dimension( 500, 200 ) );
setGlassPane( glassPane );
glassPane.setVisible( true );
pack();
setLocationRelativeTo( null );
}
public static void main( String[] args )
{
EventQueue.invokeLater( new Runnable()
{
public void run()
{
new GlassPane().setVisible(true);
}
});
}
private class MyGlassPane extends JPanel
{
public MyGlassPane()
{
MyGlassPaneMouseListenermgpml = new MyGlassPaneMouseListener();
addMouseListener( mgpml );
addMouseMotionListener( mgpml );
setOpaque( false );
}
}
private class MyGlassPaneMouseListener extends MouseInputAdapter
{
public void mouseClicked( MouseEvent me ) { redespatch( me ); }
public void mouseDragged( MouseEvent me ) { redespatch( me ); }
public void mouseEntered( MouseEvent me ) { redespatch( me ); }
public void mouseExited( MouseEvent me ) { redespatch( me ); }
public void mouseMoved( MouseEvent me ) { redespatch( me ); }
public void mousePressed( MouseEvent me ) { redespatch( me ); }
public void mouseReleased( MouseEvent me ) { redespatch( me ); }
private void
redespatch( MouseEvent me )
{
// This is the point in glass pane coordinates.
Pointgpp = me.getPoint();
// This holds container: JFrame's content pane or JMenuBar.
Containerc = GlassPane.this.getContentPane();
// This is the point in container's coordinates.
Pointcp = SwingUtilities.convertPoint( glassPane, gpp, c );
if ( cp.y < 0 )
{
c = mnbrMain;
cp = SwingUtilities.convertPoint( glassPane, gpp, c );
}
// This is the redispatching target component.
Componentrtc = SwingUtilities.getDeepestComponentAt( c, cp.x, cp.y );
if ( rtc == null )
{
return;
}
// This is the point in this component's coordinates.
PointcompPoint = SwingUtilities.convertPoint( glassPane, gpp, rtc );
// Send this mouse event on it's way.
rtc.dispatchEvent( new MouseEvent(
rtc,
me.getID(),
me.getWhen(),
me.getModifiers(),
compPoint.x,
compPoint.y,
me.getClickCount(),
me.isPopupTrigger() ) );
}
}
}