Mega Code Archive

 
Categories / Java Tutorial / Swing Event
 

Uses a subclass of MouseInputAdapter to listen to mouse events and mouse-motion events

Uses a subclass of MouseInputAdapter to listen to mouse events and mouse-motion events on the root pane's glass pane. Redispatches the events to underlying components. /*  *  * Copyright (c) 1998 Sun Microsystems, Inc. All Rights Reserved.  *  * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,  * modify and redistribute this software in source and binary code form,  * provided that i) this copyright notice and license appear on all copies of  * the software; and ii) Licensee does not utilize the software in a manner  * which is disparaging to Sun.  *  * This software is provided "AS IS," without a warranty of any kind. ALL  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY  * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR  * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE  * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING  * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS  * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,  * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER  * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF  * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE  * POSSIBILITY OF SUCH DAMAGES.  *  * This software is not designed or intended for use in on-line control of  * aircraft, air traffic, aircraft navigation or aircraft communications; or in  * the design, construction, operation or maintenance of any nuclear  * facility. Licensee represents and warrants that it will not use or  * redistribute the Software for such purposes.  */ import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.Point; import java.awt.Toolkit; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.MouseEvent; import javax.swing.AbstractButton; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.SwingUtilities; import javax.swing.event.MouseInputAdapter; /** A 1.4 application that requires no other files. */ public class GlassPaneDemo {   static private MyGlassPane myGlassPane;   /**    * Create the GUI and show it. For thread safety, this method should be    * invoked from the event-dispatching thread.    */   private static void createAndShowGUI() {     // Create and set up the window.     JFrame frame = new JFrame("GlassPaneDemo");     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     // Start creating and adding components.     JCheckBox changeButton = new JCheckBox("Glass pane \"visible\"");     changeButton.setSelected(false);     // Set up the content pane, where the "main GUI" lives.     Container contentPane = frame.getContentPane();     contentPane.setLayout(new FlowLayout());     contentPane.add(changeButton);     contentPane.add(new JButton("Button 1"));     contentPane.add(new JButton("Button 2"));     // 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 and is an item listener on the change     // button.     myGlassPane = new MyGlassPane(changeButton, menuBar, frame.getContentPane());     changeButton.addItemListener(myGlassPane);     frame.setGlassPane(myGlassPane);     // Show the window.     frame.pack();     frame.setVisible(true);   }   public static void main(String[] args) {     // Schedule a job for the event-dispatching thread:     // creating and showing this application's GUI.     javax.swing.SwingUtilities.invokeLater(new Runnable() {       public void run() {         createAndShowGUI();       }     });   } } /**  * We have to provide our own glass pane so that it can paint.  */ class MyGlassPane extends JComponent implements ItemListener {   Point point;   // React to change button clicks.   public void itemStateChanged(ItemEvent e) {     setVisible(e.getStateChange() == ItemEvent.SELECTED);   }   protected void paintComponent(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;   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);   }   public void mouseDragged(MouseEvent e) {     redispatchMouseEvent(e, false);   }   public void mouseClicked(MouseEvent e) {     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);   }   // A more finished version of this method would   // handle mouse-dragged events specially.   private void redispatchMouseEvent(MouseEvent e, boolean repaint) {     Point glassPanePoint = e.getPoint();     Container container = contentPane;     Point containerPoint = SwingUtilities.convertPoint(glassPane, glassPanePoint, contentPane);     if (containerPoint.y < 0) { // we're not in the content pane       if (containerPoint.y + menuBar.getHeight() >= 0) {         // The mouse event is over the menu bar.         // Could handle specially.       } else {         // The mouse event is over non-system window         // decorations, such as the ones provided by         // the Java look and feel.         // Could handle specially.       }     } else {       // The mouse event is probably over the content pane.       // Find out exactly which component it's over.       Component component = SwingUtilities.getDeepestComponentAt(container, containerPoint.x,           containerPoint.y);       if ((component != null) && (component.equals(liveButton))) {         // Forward events over the check box.         Point componentPoint = SwingUtilities.convertPoint(glassPane, glassPanePoint, component);         component.dispatchEvent(new MouseEvent(component, e.getID(), e.getWhen(), e.getModifiers(),             componentPoint.x, componentPoint.y, e.getClickCount(), e.isPopupTrigger()));       }     }     // Update the glass pane if requested.     if (repaint) {       glassPane.setPoint(glassPanePoint);       glassPane.repaint();     }   } }