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.IPrimitiveAction; 016import org.openstreetmap.josm.data.osm.IPrimitive; 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<IPrimitiveAction> 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 IPrimitiveAction) { 056 primitiveActions.add((IPrimitiveAction) 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 IPrimitiveAction) { 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 && ((JMenuItem) elements[i]).getAction() == a) { 077 menu.remove(i); 078 return; 079 } 080 } 081 } 082 } 083 084 /** 085 * Adds a <code>PopupMenu</code> listener. 086 * 087 * @param l the <code>PopupMenuListener</code> to add 088 * @see JPopupMenu#addPopupMenuListener 089 */ 090 public void addListener(PopupMenuListener l) { 091 menu.addPopupMenuListener(l); 092 } 093 094 /** 095 * Removes a <code>PopupMenu</code> listener. 096 * 097 * @param l the <code>PopupMenuListener</code> to remove 098 * @see JPopupMenu#removePopupMenuListener 099 */ 100 public void removeListener(PopupMenuListener l) { 101 menu.removePopupMenuListener(l); 102 } 103 104 /** 105 * Returns all enabled primitive actions. 106 * @return All primitive actions that have been added. 107 * @see #addAction(Action) 108 * @since 13957 (signature) 109 */ 110 public Collection<IPrimitiveAction> getPrimitiveActions() { 111 return Collections.unmodifiableCollection(primitiveActions); 112 } 113 114 /** 115 * Specifies the working set of primitives for all primitive actions. 116 * @param primitives The new working set of primitives. Can be null or empty 117 * @see IPrimitiveAction#setPrimitives 118 * @since 13957 (signature) 119 */ 120 public void setPrimitives(Collection<? extends IPrimitive> primitives) { 121 for (IPrimitiveAction action : primitiveActions) { 122 action.setPrimitives(primitives); 123 } 124 } 125}