Solved

JFrame + mouseListener

Posted on 2002-05-20
7
1,660 Views
Last Modified: 2013-11-23
Hi,

I have a java applet which loads a JFrame
now this JFrame has many components

When I press a button , it loads a JWindow

if this JWindow is visible then I want to hide it
if the user presses either the escape key anywhere in the frame or if he clicks a mouse anywhere in the frame

This is the code

 /**add key listener to the root pane**/
    protected JRootPane createRootPane()
    {

        MouseListener mouseListener = new MouseAdapter()
        {
            public void mouseClicked(MouseEvent event)
            {
                setVisible(false);
            }
        };

        /**add the keyboard listener*/
        ActionListener actionListener = new ActionListener()
        {
            public void actionPerformed(ActionEvent actionEvent)
            {
                setVisible(false);
            }
        };
        JRootPane rootPane = new JRootPane();
        KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
        rootPane.registerKeyboardAction(actionListener, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW);

        rootPane.addMouseListener(mouseListener);
        return rootPane;
    }


I am able to intercept the "Escape" key anywhere in the frame

But I am not able to trace mouse click events

What should I do to get the mouseClicked event
when evr user clicks the mouse anywhere in the JFrame

maybe I have to add MouseListener recursively as componets get added to the JFrame

but is there a better approcah

please help
0
Comment
Question by:sanjay_thakur
  • 4
  • 3
7 Comments
 
LVL 4

Author Comment

by:sanjay_thakur
ID: 7022174
I guess I will have to add mouseListener
for all the child components of the JFrame

but is there a better approcah?
0
 
LVL 19

Accepted Solution

by:
Jim Cakalic earned 50 total points
ID: 7022499
I'm not sure whether there is a _better_ way than what I am about to suggest. But as I recall, this way works. Basically, you have to use the GlassPane of the JFrame set to visible so that it will intercept all the mouse events occurring in the frame and redispatch (or not) to the appropriate components if desired. Here is the sample code (slightly modified) from the Java Tutorial for GlassPaneDemo that does this. The original can be found here:
    http://java.sun.com/docs/books/tutorial/uiswing/components/example-swing/index.html#GlassPaneDemo
with the relevant part of the tutorial here:
    http://java.sun.com/docs/books/tutorial/uiswing/components/rootpane.html

---------- GlassPaneDemo.java ----------
import javax.swing.*;
import javax.swing.event.MouseInputAdapter;
import java.awt.*;
import java.awt.event.*;

public class GlassPaneDemo {
    static private MyGlassPane myGlassPane;

    public static void main(String[] args) {
        JFrame frame = new JFrame("GlassPaneDemo");
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        JCheckBox changeButton = new JCheckBox("Glass pane \"visible\"");
        changeButton.setSelected(false);
        changeButton.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                myGlassPane.setVisible(e.getStateChange()
                    == ItemEvent.SELECTED);
            }
        });

        JButton button1 = new JButton("Button 1");
        button1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.out.println("Pressed Button 1");
            }
        });
        JButton button2 = new JButton("Button 2");
        button2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.out.println("Pressed Button 2");
            }
        });

        //Set up the content pane, where the "main GUI" lives.
        Container contentPane = frame.getContentPane();
        contentPane.setLayout(new FlowLayout());
        contentPane.add(changeButton);
        contentPane.add(button1);
        contentPane.add(button2);

        //Set up the menu bar, which appears above the content pane.
        JMenuBar menuBar = new JMenuBar();
        JMenu menu = new JMenu("Menu");
        menu.add(new JMenuItem("Do nothing"));
        menuBar.add(menu);
        frame.setJMenuBar(menuBar);

        //Set up the glass pane, which appears over both menu bar
        //and content pane.
        myGlassPane = new MyGlassPane(changeButton, menuBar, frame.getContentPane());
        frame.setGlassPane(myGlassPane);

        frame.pack();
        frame.setVisible(true);
    }
}

/**
 * We have to provide our own glass pane so that it can paint.
 */
class MyGlassPane extends JComponent {
    Point point;

    public void paint(Graphics g) {
        if (point != null) {
            g.setColor(Color.red);
            g.fillOval(point.x - 10, point.y - 10, 20, 20);
        }
    }

    public void setPoint(Point p) {
        point = p;
    }

    public MyGlassPane(AbstractButton aButton,
        JMenuBar menuBar,
        Container contentPane) {
        CBListener listener = new CBListener(aButton, menuBar, this, contentPane);
        addMouseListener(listener);
        addMouseMotionListener(listener);
    }
}

/**
 * Listen for all events that our check box is likely to be
 * interested in.  Redispatch them to the check box.
 */
class CBListener extends MouseInputAdapter {
    Toolkit toolkit;
    Component liveButton;
    JMenuBar menuBar;
    MyGlassPane glassPane;
    Container contentPane;
    boolean inDrag = false;

    public CBListener(Component liveButton, JMenuBar menuBar,
        MyGlassPane glassPane, Container contentPane) {
        toolkit = Toolkit.getDefaultToolkit();
        this.liveButton = liveButton;
        this.menuBar = menuBar;
        this.glassPane = glassPane;
        this.contentPane = contentPane;
    }

    public void mouseMoved(MouseEvent e) {
        redispatchMouseEvent(e, false);
    }

    /*
     * We must forward at least the mouse drags that started
     * with mouse presses over the check box.  Otherwise,
     * when the user presses the check box then drags off,
     * the check box isn't disarmed -- it keeps its dark
     * gray background or whatever its L&F uses to indicate
     * that the button is currently being pressed.
     */
    public void mouseDragged(MouseEvent e) {
        redispatchMouseEvent(e, false);
    }

    public void mouseClicked(MouseEvent e) {
        System.out.println("Mouse clicked!");
        redispatchMouseEvent(e, false);
    }

    public void mouseEntered(MouseEvent e) {
        redispatchMouseEvent(e, false);
    }

    public void mouseExited(MouseEvent e) {
        redispatchMouseEvent(e, false);
    }

    public void mousePressed(MouseEvent e) {
        redispatchMouseEvent(e, false);
    }

    public void mouseReleased(MouseEvent e) {
        redispatchMouseEvent(e, true);
        inDrag = false;
    }

    private void redispatchMouseEvent(MouseEvent e, boolean repaint) {
        boolean inButton = false;
        boolean inMenuBar = false;
        Point glassPanePoint = e.getPoint();
        Component component = null;
        Container container = contentPane;
        Point containerPoint = SwingUtilities.convertPoint(
            glassPane,
            glassPanePoint,
            contentPane);
        int eventID = e.getID();

        if (containerPoint.y < 0) {
            inMenuBar = true;
            container = menuBar;
            containerPoint = SwingUtilities.convertPoint(
                glassPane,
                glassPanePoint,
                menuBar);
            testForDrag(eventID);
        }

        //XXX: If the event is from a component in a popped-up menu,
        //XXX: then the container should probably be the menu's
        //XXX: JPopupMenu, and containerPoint should be adjusted
        //XXX: accordingly.
        component = SwingUtilities.getDeepestComponentAt(
            container,
            containerPoint.x,
            containerPoint.y);

        if (component == null) {
            return;
        }

        if (component.equals(liveButton)) {
            inButton = true;
            testForDrag(eventID);
        }

//        if (inMenuBar || inButton || inDrag) {
            Point componentPoint = SwingUtilities.convertPoint(
                glassPane,
                glassPanePoint,
                component);
            component.dispatchEvent(new MouseEvent(component,
                eventID,
                e.getWhen(),
                e.getModifiers(),
                componentPoint.x,
                componentPoint.y,
                e.getClickCount(),
                e.isPopupTrigger()));
//        }

        if (repaint) {
            toolkit.beep();
            glassPane.setPoint(glassPanePoint);
            glassPane.repaint();
        }
    }

    private void testForDrag(int eventID) {
        if (eventID == MouseEvent.MOUSE_PRESSED) {
            inDrag = true;
        }
    }
}
---------- end ----------

Best regards,
Jim Cakalic
0
 
LVL 4

Author Comment

by:sanjay_thakur
ID: 7024505
Hi Jim,

Is there any thing simpler

I am using jdk1.4
any new feature to handle this which I am not aware of?


0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 19

Expert Comment

by:Jim Cakalic
ID: 7024646
Nothing that I can find. Seems use of glass pane is still the way to globally intercept mouse events. I use the word "intercept" here because in AWT, a mouse action is considered to occur in a particular component if and only if the mouse cursor is over the unobscured part of the component's bounds when the action happens. Component bounds can be obscured by the visible component's children or by a menu or by a top-level window. In the case of JFrame, all the components you create and add to the content pane obscure the JFrame itself. Therefore, the JFrame, while it can be a mouse listener, will only receive mouse events when the mouse cursor is in an area not occupied by one of its child components. The glass pane is an "overlay" that, when visible, obscures everything else although it itself is by default transparent. But events cannot pass through it to the underlying components unless you choose to redispatch them directly.

Jim
0
 
LVL 4

Author Comment

by:sanjay_thakur
ID: 7027439
Hi Jim,
I guess you are correct this is the only option
I will try out the code.

Please give me a couple of days.

Thanks for all the help.
0
 
LVL 19

Expert Comment

by:Jim Cakalic
ID: 7027457
OK. Post back if you need anything more.
0
 
LVL 4

Author Comment

by:sanjay_thakur
ID: 7111171
My apologies for the delay.

Thanks a ton for all your help.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

By the end of 1980s, object oriented programming using languages like C++, Simula69 and ObjectPascal gained momentum. It looked like programmers finally found the perfect language. C++ successfully combined the object oriented principles of Simula w…
Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
Viewers will learn about basic arrays, how to declare them, and how to use them. Introduction and definition: Declare an array and cover the syntax of declaring them: Initialize every index in the created array: Example/Features of a basic arr…
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now