package iiuf.swing;
import java.util.ArrayList;
import java.util.HashMap;
import java.awt.Component;
import java.awt.Container;
import java.awt.Point;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
/**
Context menu manager implementation.
(c) 2000, 2001, IIUF, DIUF<p>
@author $Author: ohitz $
@version $Name: $ $Revision: 1.1 $
*/
public class ContextMenuManager
implements
MouseListener
{
private ContextMenuEnabled cme;
private ArrayList menusa = new ArrayList();
private ContextMenu[] menus = new ContextMenu[0];
private HashMap menuCache = new HashMap();
private Object lastObject;
/**
Create a new context menu manager.
*/
public ContextMenuManager() {
this(null);
}
/**
Create a new context menu manager for the component <code>cmp</code>.
@param cmp The component managed by this manager.
*/
public ContextMenuManager(ContextMenuEnabled cmp) {
if(cmp != null)
setComponent(cmp);
}
private void setupML(Component cmp, boolean add) {
if(cmp instanceof Container) {
Component[] cmps = ((Container)cmp).getComponents();
for(int i = 0; i < cmps.length; i++)
if(cmps[i] instanceof Component)
setupML(cmps[i], add);
} else if(cmp instanceof JScrollPane) {
if(((JScrollPane)cmp).getViewport().getView() instanceof Component)
setupML(((JScrollPane)cmp).getViewport().getView(), add);
return;
}
if(add)
cmp.addMouseListener(this);
else
cmp.removeMouseListener(this);
}
/**
Set the managed component to <code>cmp</code>.
@param cmp The component managed by this manager.
*/
public void setComponent(ContextMenuEnabled cmp) {
removeComponent();
cme = cmp;
setupML(cme.getComponent(), true);
cme.setContextMenuManager(this);
}
/**
Get the managed component.
@returns The component managed by this manager.
*/
public ContextMenuEnabled getComponent() {
return cme;
}
/**
Remove the managed component.
*/
public void removeComponent() {
if(cme == null) return;
Object[] popups = menuCache.values().toArray();
for(int i = 0; i < popups.length; i++)
if(cme.getComponent() instanceof Container)
((Container)cme.getComponent()).remove((JPopupMenu)popups[i]);
menuCache = new HashMap();
setupML(cme.getComponent(), false);
cme = null;
}
/**
Register a context menu with this manager.
The menu will be added to the tail of the registred menus.
@param menu The menu to register.
*/
public void addContextMenu(ContextMenu menu) {
addContextMenu(menu, false);
}
/**
Register a context menu with this manager.
@param menu The menu to register.
@param asFirst Add this menu as first menu in popup.
*/
public void addContextMenu(ContextMenu menu, boolean asFirst) {
if(asFirst)
menusa.add(0, menu);
else
menusa.add(menu);
menus = (ContextMenu[])menusa.toArray(new ContextMenu[menusa.size()]);
}
/**
Deregister a context menu with this manager.
@param menu The menu to register.
*/
public void removeContextMenu(ContextMenu menu) {
menusa.remove(menu);
menus = (ContextMenu[])menusa.toArray(new ContextMenu[menusa.size()]);
}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {handlePopUp(e);}
public void mousePressed(MouseEvent e) {handlePopUp(e);}
private void handlePopUp(MouseEvent e) {
if(!e.isPopupTrigger()) return;
lastObject = cme.locationToObject(e.getComponent(), e.getPoint());
if(lastObject == null) return;
boolean[] menubm = new boolean[menus.length];
int lastitem = -1;
for(int i = 0; i < menus.length; i++) {
menubm[i] = menus[i].check(lastObject);
if(menubm[i]) lastitem = i;
}
JPopupMenu popup = (JPopupMenu)menuCache.get(menubm);
if(popup == null) {
popup = new JPopupMenu();
for(int i = 0; i < menubm.length; i++)
if(menubm[i]) {
JMenuItem[] mi = menus[i].getItems();
for(int j = 0; j < mi.length; j++)
popup.add(mi[j]);
if(i != lastitem) popup.addSeparator();
}
menuCache.put(menubm, popup);
if(cme instanceof Container)
((Container)cme.getComponent()).add(popup);
}
lastLocation = e.getPoint();
if(popup.getComponentCount() > 0)
popup.show(e.getComponent(), lastLocation.x, lastLocation.y);
}
private Point lastLocation = new Point();
/**
Get last menu popup location.
@return Last location of popup menu or (0,0) if no menu did popup yet.
*/
public Point getLastMenuLocation() {
return lastLocation;
}
/**
Get object under last menu location.
@return Last object under the menu location or null.
*/
public Object getLastObject() {
return lastObject;
}
}
/*
$Log: ContextMenuManager.java,v $
Revision 1.1 2002/07/11 12:09:52 ohitz
Initial checkin
Revision 1.7 2001/03/11 17:59:38 schubige
Fixed various soundium and iiuf.swing.graph bugs
Revision 1.6 2001/02/11 16:25:39 schubige
working on soundium
Revision 1.5 2001/01/14 13:21:13 schubige
Win NT update
Revision 1.4 2001/01/04 16:28:38 schubige
Header update for 2001 and DIUF
Revision 1.3 2000/12/18 12:39:09 schubige
Added ports to iiuf.util.graph
Revision 1.2 2000/10/10 16:32:12 schubige
Added subtree display to TreeView, fixed some bugs
Revision 1.1 2000/10/03 08:39:39 schubige
Added tree view and contect menu stuff
*/