Package net.helipilot50.stocktrade.displayproject

Source Code of net.helipilot50.stocktrade.displayproject.GlassPaneWithEvents

/*
Copyright (c) 2003-2009 ITerative Consulting Pty Ltd. All Rights Reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:

o Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
 
o Redistributions in binary form must reproduce the above copyright notice, this list of conditions
and the following disclaimer in the documentation and/or other materials provided with the distribution.
   
o This jcTOOL Helper Class software, whether in binary or source form may not be used within,
or to derive, any other product without the specific prior written permission of the copyright holder

 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


*/
package net.helipilot50.stocktrade.displayproject;

import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import net.helipilot50.stocktrade.framework.LogMgr;

import sun.awt.dnd.SunDropTargetEvent;

/**
* This glass pane component will stop all mouse events, except for a double click.
*
* If the first mouse click it receives is a double click, then it will pass that
* event on, as it means a single click has just occurred before it (the glass pane)
* was displayed.  If it receives any other click events before a double click
* event, then it will not pass on the double click.  Also, once it has received
* a double click event, it will not pass on any other double click events.
*
* This logic will be reset when the glass pane gets set to invisible/visible.
*
* This GlassPaneWithEvents component will be installed on the window when
* {@link UIutils#getGlassPane(Component)} is called.
*
* @author Craig Mitchell
* @since 31/03/2008
*/
@SuppressWarnings("serial")
public class GlassPaneWithEvents extends JComponent implements MouseListener {
    /**
     * A flag to indicate whether the glass pane is to be coloured
     * to aid with the debugging effort. -DLogFlags="(trc:ui:2:255)"
     */
    protected static boolean colouredGlassForDebug = LogMgr.getInstance().test(LogMgr.TYPE_DEBUG, LogMgr.SERVICE_UI, 2, 255);

    /**
     * Store the content pane we are blocking
     */
    private Container contentPane;
   
    /**
     * This works out if a double click event will be allowed to be passed through
     */
    private boolean doubleClickAllowed;

    /**
     * This is the current event we're processing. If no event is currently being processed then this will be
     * null, however, this field can only be read by the EDT which will be waiting when not processing an event
     * this should never be read as null.
     */
  private static AWTEvent currentEvent = null;
 
  static {
    // DK:30/10/2008:intercept KeyEvents to consume all key actions once the GlassPane is visible.
    //Allow one KeyRelese event once KeyPressed event was registered before the GlassPane become visible.
    //KeyRelese event need to be allowed to complete Alt+Key actions as well as DefaultButton actions.
    //In other case the action will be ignored due GlassPane is become visible in between Key Pressed and Released events.
    // TF:20/11/2009:Forced this action to be done on the EDT
    UIutils.invokeOnGuiThread(new Runnable() {
      public void run() {
        Toolkit.getDefaultToolkit().getSystemEventQueue().push(new EventQueue() {
          private Object lastPressedComponent = null;

          @Override
          protected void dispatchEvent(AWTEvent event) {
            if (event instanceof KeyEvent && event.getSource() != null) {
              Component glassPane = null;
              if (event.getSource() instanceof JFrame) {
                glassPane = ((JFrame) event.getSource()).getRootPane().getGlassPane();
              } else if (event.getSource() instanceof JComponent) {
                JFrame frame = UIutils.getWindowForComponent((JComponent)event.getSource());
                if (frame != null) {
                  glassPane = frame.getRootPane().getGlassPane();
                }
              }
              if (glassPane != null) {
                if (glassPane.isVisible()) {
                  if (event.getID() == KeyEvent.KEY_RELEASED
                      && lastPressedComponent == event.getSource()) {
                    //allow last pressed component to process release action
                    lastPressedComponent = null;
                  } else {
                    ((KeyEvent) event).consume();
                  }
                } else {
                  if (event.getID() == KeyEvent.KEY_PRESSED) {
                    //remember last pressed component
                    lastPressedComponent  = event.getSource();
                  }
                }
              }
            }
            currentEvent = event;
            try {
              super.dispatchEvent(event);
              //Bart Gauquie 2010/03/04: click mouse button and release mousebutton on a CompoundGraphic which is within a CompoundGraphic does not generate:
              //java.awt.event.MouseEvent[MOUSE_PRESSED,(902,222),button=1,modifiers=Button1,extModifiers=Button1,clickCount=1] on A3_MainHIC
              //java.awt.event.MouseEvent[MOUSE_RELEASED,(902,222),button=1,modifiers=Button1,clickCount=1] on A3_MainHIC
              //
              //but
              //
              //java.awt.event.MouseEvent[MOUSE_PRESSED,(920,224),button=1,modifiers=Button1,extModifiers=Button1,clickCount=1] on A3_MainHIC
              //java.awt.event.InvocationEvent[INVOCATION_DEFAULT,runnable=sun.awt.dnd.SunDragSourceContextPeer$1@d8dcac,notifier=null,catchExceptions=false,when=1267698736927] on sun.awt.windows.WToolkit@330fb9
              //sun.awt.dnd.SunDropTargetEvent[MOUSE_ENTERED,(920,224),button=0,clickCount=0] on A3_MainHIC
              //sun.awt.PeerEvent[INVOCATION_DEFAULT,runnable=sun.awt.windows.WDropTargetContextPeer$1@1ffb136,notifier=null,catchExceptions=false,when=1267698736990] on A3_MainHIC
              //sun.awt.PeerEvent[INVOCATION_DEFAULT,runnable=sun.awt.dnd.SunDragSourceContextPeer$EventDispatcher@1b23800,notifier=null,catchExceptions=false,when=1267698736990] on be.brail.displayproject.controls.TextGraphic[,1,1,34x10,alignmentX=0.0,alignmentY=0.0,border=,flags=58720256,maximumSize=,minimumSize=java.awt.Dimension[width=34,height=10],preferredSize=java.awt.Dimension[width=34,height=10],defaultIcon=,disabledIcon=,horizontalAlignment=LEADING,horizontalTextPosition=TRAILING,iconTextGap=4,labelFor=,text=EE47897,verticalAlignment=CENTER,verticalTextPosition=CENTER]
              //sun.awt.dnd.SunDropTargetEvent[MOUSE_DROPPED,(920,224)] on A3_MainHIC
              //
              // so we create a new MouseReleased event with the same coordinates and dispatch that event also ...
              if (event instanceof SunDropTargetEvent) {
                SunDropTargetEvent sunDropTargetEvent = (SunDropTargetEvent) event;
                if (sunDropTargetEvent.getID() == SunDropTargetEvent.MOUSE_DROPPED) {
                  MouseEvent mouseReleasedEvent = new MouseEvent((Component) event.getSource(), MouseEvent.MOUSE_RELEASED, sunDropTargetEvent.getWhen(),
                      MouseEvent.BUTTON1_MASK, sunDropTargetEvent.getX(), sunDropTargetEvent.getY(), 1, false, MouseEvent.BUTTON1);
                  super.dispatchEvent(mouseReleasedEvent);
                }
              }
            }
            finally {
              currentEvent = null;
            }
          }
        });     
      }
    });
  }

  /**
   * Return the current event. This method will return null unless the calling thread is the event dispatching
   * thread, and the event dispatching thread is processing an event. (If the former condition is true, the
   * latter condition is almost certain)
   * @return
   */
  public static AWTEvent getCurrentEvent() {
    if (SwingUtilities.isEventDispatchThread()) {
      return currentEvent;
    }
    else {
      return null;
    }
  }
 
  /**
   * Main constructor.
   *
   * @param pContentPane The content pane that is directly below this glass pane.
   */
  public GlassPaneWithEvents(Container pContentPane) {
    this.addMouseListener(this);
    this.contentPane = pContentPane;
    this.doubleClickAllowed = true;
  }

  /**
   * Take the mouse event and repost it on the appropriate widget.
   *
   * @param pEvent
   * @param repaint
   */
  private void redispatchMouseEvent(MouseEvent pEvent) {
    // Get the mouse click point relative to the content pane
    Point containerPoint = SwingUtilities.convertPoint(this, pEvent.getPoint(), this.contentPane);

    // Find the component that is under this point
    Component component = SwingUtilities.getDeepestComponentAt(
        this.contentPane,
        containerPoint.x,
        containerPoint.y);

    // Return if nothing was found
    if (component == null) {
      return;
    }

    // Convert point relative to the target component
    Point componentPoint = SwingUtilities.convertPoint(
        this,
        pEvent.getPoint(),
        component);

    // Redispatch the event
    component.dispatchEvent(new MouseEvent(component,
        pEvent.getID(),
        pEvent.getWhen(),
        pEvent.getModifiers(),
        componentPoint.x,
        componentPoint.y,
        pEvent.getClickCount(),
        pEvent.isPopupTrigger()));
  }

  /**
   * MouseClicked is the only event we care to redispatch.
   *
   * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
   */
  public void mouseClicked(MouseEvent e) {
    // If we are a double click event, and we are allowed to happen.  Redispatch the event.
    if (e.getClickCount() == 2 && this.doubleClickAllowed) {
      this.redispatchMouseEvent(e);
    }
    // Any thing other then a double click, and even after we have done a double click, we disable all further double click events.
    this.doubleClickAllowed = false;
  }

  // Ignored events ...
  public void mouseEntered(MouseEvent e) {}
  public void mouseExited(MouseEvent e) {}
  // DK:02/03/2009: redispatch mouse Pressed and Released events either.
  //because some of listeners are listening for mouse press/release events to process double click events
  //If glass pane has been shown in between of two clicks then mouse press/release/click events with the second click
  //will come to glass pane. That is why we need to redispatch them.
  public void mousePressed(MouseEvent e) {
    if (e.getClickCount() == 2 && this.doubleClickAllowed) {
      redispatchMouseEvent(e);
    }
  }
  public void mouseReleased(MouseEvent e) {
    if (e.getClickCount() == 2 && this.doubleClickAllowed) {
      redispatchMouseEvent(e);
    }
  }

  /**
   * Reset our doubleClickAllowed flag.
   *
   * @see javax.swing.JComponent#setVisible(boolean)
   */
  @Override
  public void setVisible(boolean flag) {
    super.setVisible(flag);

    // We we are set to displayed, then allow double click events
    this.doubleClickAllowed = true;
  }
 
  @Override
  public void paint(Graphics g) {
    if (colouredGlassForDebug) {
      g.setColor(Color.cyan);
      g.fillRect(0, 0, g.getClipBounds().width, g.getClipBounds().height);
      g.setColor(Color.black);
      int x = Math.max(g.getClipBounds().width, 1) / 2 - 20;
      int y = Math.max(g.getClipBounds().height, 1) / 2 - 7;
      g.drawString("LOCKED", x, y);
    }
  }
}
TOP

Related Classes of net.helipilot50.stocktrade.displayproject.GlassPaneWithEvents

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.