package org.openflexo.fib.editor.controller; import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.util.Hashtable; import java.util.logging.Logger; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPopupMenu; import org.openflexo.fib.editor.controller.EditorAction.ActionAvailability; import org.openflexo.fib.editor.controller.EditorAction.ActionPerformer; import org.openflexo.fib.model.BorderLayoutConstraints; import org.openflexo.fib.model.BorderLayoutConstraints.BorderLayoutLocation; import org.openflexo.fib.model.FIBComponent; import org.openflexo.fib.model.FIBContainer; import org.openflexo.fib.model.FIBModelObject; import org.openflexo.fib.model.FIBPanel; import org.openflexo.fib.model.FIBPanel.Border; import org.openflexo.fib.model.FIBPanel.Layout; import org.openflexo.fib.model.FIBSplitPanel; import org.openflexo.fib.model.SplitLayoutConstraints; import org.openflexo.logging.FlexoLogger; public class ContextualMenu { private static final Logger logger = FlexoLogger.getLogger(ContextualMenu.class.getPackage().getName()); private FIBEditorController editorController; private Hashtable<EditorAction, PopupMenuItem> actions; private JPopupMenu menu; public ContextualMenu(FIBEditorController anEditorController) { this.editorController = anEditorController; actions = new Hashtable<EditorAction, PopupMenuItem>(); menu = new JPopupMenu(); addToActions(new EditorAction("Inspect", null, new ActionPerformer() { @Override public FIBModelObject performAction(FIBModelObject object) { editorController.getEditor().getInspector().setVisible(true); return object; } }, new ActionAvailability() { @Override public boolean isAvailableFor(FIBModelObject object) { return object != null; } })); addToActions(new EditorAction("Delete", FIBEditorIconLibrary.DELETE_ICON, new ActionPerformer() { @Override public FIBModelObject performAction(FIBModelObject object) { FIBComponent parent = ((FIBComponent) object).getParent(); boolean deleteIt = JOptionPane.showConfirmDialog(editorController.getEditor().getFrame(), object + ": really delete this component (undoable operation) ?", "information", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE) == JOptionPane.YES_OPTION; if (deleteIt) { logger.info("Removing object " + object); object.delete(); } return parent; } }, new ActionAvailability() { @Override public boolean isAvailableFor(FIBModelObject object) { return object instanceof FIBComponent; } })); addToActions(new EditorAction("Wrap with panel", null, new ActionPerformer() { @Override public FIBModelObject performAction(FIBModelObject object) { FIBComponent component = (FIBComponent) object; FIBContainer parent = component.getParent(); parent.removeFromSubComponents(component); FIBPanel newPanel = new FIBPanel(); newPanel.setLayout(Layout.border); newPanel.setBorder(Border.titled); newPanel.finalizeDeserialization(); parent.addToSubComponents(newPanel, component.getConstraints()); newPanel.addToSubComponents(component, new BorderLayoutConstraints(BorderLayoutLocation.center)); return parent; } }, new ActionAvailability() { @Override public boolean isAvailableFor(FIBModelObject object) { return object instanceof FIBComponent && ((FIBComponent) object).getParent() != null; } })); addToActions(new EditorAction("Wrap with split panel", null, new ActionPerformer() { @Override public FIBModelObject performAction(FIBModelObject object) { FIBComponent component = (FIBComponent) object; FIBContainer parent = component.getParent(); parent.removeFromSubComponents(component); FIBSplitPanel newPanel = new FIBSplitPanel(); newPanel.makeDefaultHorizontalLayout(); parent.addToSubComponents(newPanel, component.getConstraints()); newPanel.addToSubComponents(component, SplitLayoutConstraints.makeSplitLayoutConstraints(newPanel.getFirstEmptyPlaceHolder())); return parent; } }, new ActionAvailability() { @Override public boolean isAvailableFor(FIBModelObject object) { return object instanceof FIBComponent && ((FIBComponent) object).getParent() != null; } })); } public void addToActions(EditorAction action) { PopupMenuItem newMenuItem = new PopupMenuItem(action); menu.add(newMenuItem); actions.put(action, newMenuItem); } public void displayPopupMenu(FIBModelObject object, Component invoker, MouseEvent e) { for (EditorAction action : actions.keySet()) { PopupMenuItem menuItem = actions.get(action); menuItem.setObject(object); } menu.show(invoker, e.getPoint().x, e.getPoint().y); } class PopupMenuItem extends JMenuItem { private FIBModelObject object; private EditorAction action; public PopupMenuItem(EditorAction anAction) { super(anAction.getActionName(), anAction.getActionIcon()); this.action = anAction; addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { FIBModelObject selectThis = action.getPerformer().performAction(object); if (selectThis instanceof FIBComponent) { editorController.setSelectedObject((FIBComponent) selectThis); } } }); } public FIBModelObject getObject() { return object; } public void setObject(FIBModelObject object) { this.object = object; setVisible(action.getAvailability().isAvailableFor(object)); } } }