001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui; 003 004import java.util.Collection; 005import java.util.Collections; 006import java.util.HashSet; 007import java.util.Set; 008 009import javax.swing.Action; 010import javax.swing.JMenuItem; 011import javax.swing.JPopupMenu; 012import javax.swing.MenuElement; 013import javax.swing.event.PopupMenuListener; 014 015import org.openstreetmap.josm.actions.OsmPrimitiveAction; 016import org.openstreetmap.josm.data.osm.OsmPrimitive; 017 018/** 019 * Handler to ease management of actions in different popup menus. 020 * @since 5821 021 */ 022public class PopupMenuHandler { 023 024 // Set of enabled osm primitives actions 025 private final Set<OsmPrimitiveAction> primitiveActions = new HashSet<>(); 026 // Managed menu 027 private final JPopupMenu menu; 028 029 /** 030 * Constructs a new {@code RelationActionMenuHandler} for the specified popup menu. 031 * 032 * @param menu The menu to be managed 033 */ 034 public PopupMenuHandler(JPopupMenu menu) { 035 this.menu = menu; 036 } 037 038 /** 039 * Appends a new separator at the end of the menu. 040 * @see JPopupMenu#addSeparator 041 */ 042 public void addSeparator() { 043 menu.addSeparator(); 044 } 045 046 /** 047 * Appends a new menu item to the end of the menu which dispatches the specified <code>Action</code> object. 048 * 049 * @param a the <code>Action</code> to add to the menu 050 * @return the new menu item 051 * @see JPopupMenu#add(Action) 052 */ 053 public JMenuItem addAction(Action a) { 054 if (a != null) { 055 if (a instanceof OsmPrimitiveAction) { 056 primitiveActions.add((OsmPrimitiveAction) a); 057 } 058 return menu.add(a); 059 } 060 return null; 061 } 062 063 /** 064 * Removes the menu item which dispatches the specified <code>Action</code> object. 065 * 066 * @param a the <code>Action</code> to remove from the menu 067 * @see JPopupMenu#remove(int) 068 */ 069 public void removeAction(Action a) { 070 if (a != null) { 071 if (a instanceof OsmPrimitiveAction) { 072 primitiveActions.remove(a); 073 } 074 MenuElement[] elements = menu.getSubElements(); 075 for (int i=0; i<elements.length; i++) { 076 if (elements[i] instanceof JMenuItem) { 077 if (((JMenuItem) elements[i]).getAction() == a) { 078 menu.remove(i); 079 return; 080 } 081 } 082 } 083 } 084 } 085 086 /** 087 * Adds a <code>PopupMenu</code> listener. 088 * 089 * @param l the <code>PopupMenuListener</code> to add 090 * @see JPopupMenu#addPopupMenuListener 091 */ 092 public void addListener(PopupMenuListener l) { 093 menu.addPopupMenuListener(l); 094 } 095 096 /** 097 * Removes a <code>PopupMenu</code> listener. 098 * 099 * @param l the <code>PopupMenuListener</code> to remove 100 * @see JPopupMenu#removePopupMenuListener 101 */ 102 public void removeListener(PopupMenuListener l) { 103 menu.removePopupMenuListener(l); 104 } 105 106 /** 107 * Returns all enabled primitive actions. 108 * @return All primitive actions that have been added. 109 * @see #addAction(Action) 110 */ 111 public Collection<OsmPrimitiveAction> getPrimitiveActions() { 112 return Collections.unmodifiableCollection(primitiveActions); 113 } 114 115 /** 116 * Specifies the working set of primitives for all primitive actions. 117 * @param primitives The new working set of primitives. Can be null or empty 118 * @see OsmPrimitiveAction#setPrimitives 119 */ 120 public void setPrimitives(Collection<? extends OsmPrimitive> primitives) { 121 for (OsmPrimitiveAction action : primitiveActions) { 122 action.setPrimitives(primitives); 123 } 124 } 125}