package kskb;
import java.awt.Component;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class MouseEventDispatch
{
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setSize(100, 100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
LabelPanel panel = LabelPanel.getInstance();
panel.setBounds(0, 0, 100, 100);
frame.add(panel);
Label redLabel = new Label("imgred.png", "Rot geklickt");
redLabel.setBounds(0, 0, 30, 30);
panel.add(redLabel);
Label blueLabel = new Label("imgblue.png", "Blau geklickt");
blueLabel.setBounds(15, 15, 30, 30);
panel.add(blueLabel);
frame.setVisible(true);
}
private static class LabelPanel extends JPanel
{
private static final long serialVersionUID = 1L;
private static LabelPanel INSTANCE = new LabelPanel();
private LabelPanel()
{
super(null);
}
public void mouseMoveOnLabel(MouseEvent newEvent, List<LogicLabel> list)
{
int x = newEvent.getX();
int y = newEvent.getY();
Point p = new Point(x, y);
Component[] comps = getComponents();
for(Component comp:comps)
{
if(comp instanceof Label)
{
Label label = (Label) comp;
Rectangle bounds = label.getBounds();
if(bounds.contains(p) && !list.contains(label))
{
newEvent = new MouseEvent(this,
newEvent.getID(),
newEvent.getWhen(),
newEvent.getModifiers(),
x - bounds.x,
y - bounds.y,
newEvent.getClickCount(),
newEvent.isPopupTrigger());
label.mouseMoved(newEvent, list);
}
}
}
}
public void exitLabel(LogicLabel exclutelabel)
{
Component[] comps = getComponents();
for(Component comp:comps)
{
if(comp instanceof Label)
{
Label label = (Label) comp;
if(label != exclutelabel)
label.mouseExited(null);
}
}
}
public void mouseClickOnLabel(MouseEvent newEvent, List<LogicLabel> list)
{
int x = newEvent.getX();
int y = newEvent.getY();
Point p = new Point(x, y);
Component[] comps = getComponents();
for(Component comp:comps)
{
if(comp instanceof LogicLabel)
{
Label label = (Label) comp;
Rectangle bounds = label.getBounds();
if(bounds.contains(p) && !list.contains(label))
{
newEvent = new MouseEvent(this,
newEvent.getID(),
newEvent.getWhen(),
newEvent.getModifiers(),
x - bounds.x,
y - bounds.y,
newEvent.getClickCount(),
newEvent.isPopupTrigger());
label.mouseClicked(newEvent, list);
}
}
}
}
public static LabelPanel getInstance()
{
return(INSTANCE);
}
}
/** Enthält die Weiterleitungsfunktionen. */
private static abstract class LogicLabel extends JLabel implements MouseListener, MouseMotionListener
{
private static final long serialVersionUID = 1L;
private boolean mouseEntered;
public LogicLabel()
{
super();
addMouseListener(this);
addMouseMotionListener(this);
}
private boolean mouseOnAlpha(int x, int y)
{
int rgb = 0;
if(getIcon() != null)
{
ImageIcon icon = (ImageIcon) getIcon();
BufferedImage image = (BufferedImage) icon.getImage();
rgb = image.getRGB(x, y);
}
return(((rgb >> 24) & 0x000000FF) == 0);
}
public void mouseClicked(MouseEvent e)
{
mouseClicked(e, null);
}
public void mouseClicked(MouseEvent e, List<LogicLabel> list)
{
int mouseX = e.getX();
int mouseY = e.getY();
if(!mouseOnAlpha(mouseX, mouseY))
{
mouseHasPressed();
}
else
{
if(list == null)
list = new LinkedList<LogicLabel>();
list.add(this);
MouseEvent newEvent = new MouseEvent(LabelPanel.getInstance(),
e.getID(),
e.getWhen(),
e.getModifiers(),
getX() + e.getX(),
getY() + e.getY(),
e.getClickCount(),
e.isPopupTrigger());
LabelPanel.getInstance().mouseClickOnLabel(newEvent, list);
}
}
public void mouseEntered(MouseEvent e)
{
if(!mouseEntered)
{
mouseHasEntered();
mouseEntered = true;
}
}
public void mouseExited(MouseEvent e)
{
if(mouseEntered)
{
mouseHasExited();
mouseEntered = false;
}
}
public void mouseDragged(MouseEvent e) {}
public void mouseMoved(MouseEvent e)
{
mouseMoved(e, null);
}
public void mouseMoved(MouseEvent e, List<LogicLabel> list)
{
int mouseX = e.getX();
int mouseY = e.getY();
if(!mouseOnAlpha(mouseX, mouseY))
{
LabelPanel.getInstance().exitLabel(this);
mouseEntered(e);
}
else
{
mouseExited(e);
if(list == null)
list = new LinkedList<LogicLabel>();
list.add(this);
MouseEvent newEvent = new MouseEvent(LabelPanel.getInstance(),
e.getID(),
e.getWhen(),
e.getModifiers(),
getX() + e.getX(),
getY() + e.getY(),
e.getClickCount(),
e.isPopupTrigger());
LabelPanel.getInstance().mouseMoveOnLabel(newEvent, list);
}
}
public abstract void mouseHasEntered();
public abstract void mouseHasExited();
public abstract void mouseHasPressed();
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
}
/** Das Label. */
private static class Label extends LogicLabel
{
private static final long serialVersionUID = 1L;
private String clickMsg;
public Label(String imgPath, String clickMsg)
{
this.clickMsg = clickMsg;
try
{
setIcon(new ImageIcon(ImageIO.read(new File(imgPath))));
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void mouseHasEntered()
{
}
public void mouseHasExited()
{
}
public void mouseHasPressed()
{
System.out.println(clickMsg);
}
}
}