/* * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata * * Portions of this software were developed by the Unidata Program at the * University Corporation for Atmospheric Research. * * Access and use of this software shall impose the following obligations * and understandings on the user. The user is granted the right, without * any fee or cost, to use, copy, modify, alter, enhance and distribute * this software, and any derivative works thereof, and its supporting * documentation for any purpose whatsoever, provided that this entire * notice appears in all copies of the software, derivative works and * supporting documentation. Further, UCAR requests that the user credit * UCAR/Unidata in any publications that result from the use of this * software or in any product that includes this software. The names UCAR * and/or Unidata, however, may not be used in any advertising or publicity * to endorse or promote any products or commercial entity unless specific * written permission is obtained from UCAR/Unidata. The user also * understands that UCAR/Unidata is not obligated to provide the user with * any support, consulting, training or assistance of any kind with regard * to the use, operation and performance of this software nor to provide * the user with any updates, revisions, new versions or "bug fixes." * * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE. */ package ucar.util.prefs.ui; import javax.swing.*; import java.awt.*; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.MouseEvent; import javax.swing.event.MouseInputAdapter; /** A 1.4 application that requires no other files. */ public class GlassPaneDemo { static private MyGlassPane myGlassPane; static private boolean state = false; /** * Create the GUI and show it. For thread safety, * this method should be invoked from the * event-dispatching thread. */ private static void createAndShowGUI() { //Make sure we have nice window decorations. //JFrame.setDefaultLookAndFeelDecorated(true); //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); JButton butt = new JButton("Button 1"); contentPane.add(butt); butt.addMouseListener( new MouseInputAdapter() { //public void mousePressed(MouseEvent e) { myGlassPane.setVisible( true); System.out.println("on");} public void mousePressed(MouseEvent e) { state = !state; myGlassPane.setVisible( state); System.out.println("state "+state); } public void mouseDragged(MouseEvent e) { myGlassPane.setVisible( false); System.out.println("drag");} }); //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(butt, 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 { 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, true); } 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); System.out.println("event "+containerPoint); 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(); } } }