package org.rr.commons.swing.components.container;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import org.rr.commons.swing.components.resources.ImageResourceBundle;
import org.rr.commons.swing.icon.AnimatedIcon;
/**
* @see http://www.java2s.com/Code/Java/Swing-JFC/Showhowaglasspanecanbeusedtoblockmouseandkeyevents.htm
*
*/
public class ShadowPanel extends JPanel implements MouseListener, MouseMotionListener, FocusListener {
Toolkit toolkit;
JMenuBar menuBar;
Container contentPane;
boolean inDrag = false;
// trigger for redispatching (allows external control)
boolean needToRedispatch = false;
public ShadowPanel(boolean animated) {
setOpaque(false);
addMouseListener(this);
addMouseMotionListener(this);
addFocusListener(this);
this.setLayout(new BorderLayout());
if(animated) {
ImageIcon progressIcon = ImageResourceBundle.getResourceAsImageIcon("progress.gif");
AnimatedIcon icon = new AnimatedIcon(progressIcon);
this.add(new JLabel(icon), BorderLayout.CENTER);
}
}
public ShadowPanel() {
this(true);
}
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f));
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
super.paintComponent(g2d);
}
public void setVisible(boolean v) {
// Make sure we grab the focus so that key events don't go astray.
if (v) {
requestFocus();
}
super.setVisible(v);
}
// Once we have focus, keep it if we're visible
public void focusLost(FocusEvent fe) {
if (isVisible())
requestFocus();
}
public void focusGained(FocusEvent fe) {
}
// We only need to redispatch if we're not visible, but having full control
// over this might prove handy.
public void setNeedToRedispatch(boolean need) {
needToRedispatch = need;
}
/*
* (Based on code from the Java Tutorial) 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) {
if (needToRedispatch)
redispatchMouseEvent(e);
}
public void mouseMoved(MouseEvent e) {
if (needToRedispatch)
redispatchMouseEvent(e);
}
public void mouseClicked(MouseEvent e) {
if (needToRedispatch)
redispatchMouseEvent(e);
}
public void mouseEntered(MouseEvent e) {
if (needToRedispatch)
redispatchMouseEvent(e);
}
public void mouseExited(MouseEvent e) {
if (needToRedispatch)
redispatchMouseEvent(e);
}
public void mousePressed(MouseEvent e) {
if (needToRedispatch)
redispatchMouseEvent(e);
}
public void mouseReleased(MouseEvent e) {
if (needToRedispatch) {
redispatchMouseEvent(e);
inDrag = false;
}
}
private void redispatchMouseEvent(MouseEvent e) {
boolean inButton = false;
boolean inMenuBar = false;
Point glassPanePoint = e.getPoint();
Component component = null;
Container container = contentPane;
Point containerPoint = SwingUtilities.convertPoint(this, glassPanePoint, contentPane);
int eventID = e.getID();
if (containerPoint.y < 0) {
inMenuBar = true;
container = menuBar;
containerPoint = SwingUtilities.convertPoint(this, 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;
} else {
inButton = true;
testForDrag(eventID);
}
if (inMenuBar || inButton || inDrag) {
Point componentPoint = SwingUtilities.convertPoint(this, glassPanePoint, component);
component.dispatchEvent(new MouseEvent(component, eventID, e.getWhen(), e.getModifiers(), componentPoint.x, componentPoint.y, e.getClickCount(), e
.isPopupTrigger()));
}
}
private void testForDrag(int eventID) {
if (eventID == MouseEvent.MOUSE_PRESSED) {
inDrag = true;
}
}
}