001 /* 002 * $Id: ContextMenuHandler.java,v 1.5 2005/10/24 13:20:46 kleopatra Exp $ 003 * 004 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle, 005 * Santa Clara, California 95054, U.S.A. All rights reserved. 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this library; if not, write to the Free Software 019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 020 */ 021 package org.jdesktop.swingx.plaf; 022 023 import java.awt.event.MouseAdapter; 024 import java.awt.event.MouseEvent; 025 026 import javax.swing.ActionMap; 027 import javax.swing.JComponent; 028 import javax.swing.JPopupMenu; 029 import javax.swing.SwingUtilities; 030 031 032 /** 033 * Responsible for showing the default PopupMenu. 034 * 035 * @author Jeanette Winzenburg 036 */ 037 public class ContextMenuHandler extends MouseAdapter { 038 039 private ActionMap actionMap; 040 041 private ContextMenuSource contextMenuSource; 042 043 private JPopupMenu popup; 044 045 /** 046 * creates a context handler for TextContextMenuSource. 047 * 048 */ 049 public ContextMenuHandler() { 050 this(null); 051 } 052 053 /** 054 * creates a context handler for the given ContextMenuSource. 055 * Defaults to TextContextMenuSource if source == null. 056 * 057 * @param source 058 */ 059 public ContextMenuHandler(ContextMenuSource source) { 060 contextMenuSource = source; 061 } 062 063 // --------------------- MouseListener 064 065 public void mousePressed(MouseEvent e) { 066 maybeShowContext(e); 067 } 068 069 public void mouseReleased(MouseEvent e) { 070 maybeShowContext(e); 071 } 072 073 private void maybeShowContext(final MouseEvent e) { 074 if (!e.isPopupTrigger() || !e.getComponent().isEnabled()) 075 return; 076 if (e.getComponent().hasFocus()) { 077 showContextPopup(e); 078 } else { 079 ((JComponent) e.getComponent()).grabFocus(); 080 SwingUtilities.invokeLater(new Runnable() { 081 public void run() { 082 showContextPopup(e); 083 } 084 }); 085 } 086 087 } 088 089 private void showContextPopup(MouseEvent e) { 090 showContextPopup((JComponent) e.getComponent(), e.getX(), e 091 .getY()); 092 093 } 094 095 private void showContextPopup(JComponent component, int x, int y) { 096 JPopupMenu popup = getPopupMenu(component, true); 097 popup.show(component, x, y); 098 } 099 100 /** 101 * @param component 102 * @return 103 */ 104 private JPopupMenu getPopupMenu(JComponent component, boolean synchEnabled) { 105 if (popup == null) { 106 popup = new JPopupMenu(); 107 ActionMap map = getActionMap(component); 108 String[] keys = getContextMenuSource().getKeys(); 109 for (int i = 0; i < keys.length; i++) { 110 if (keys[i] != null) { 111 popup.add(map.get(keys[i])); 112 } else { 113 popup.addSeparator(); 114 } 115 } 116 } 117 if (synchEnabled) { 118 getContextMenuSource().updateActionEnabled(component, actionMap); 119 } 120 121 return popup; 122 } 123 124 private ActionMap getActionMap(JComponent component) { 125 if (actionMap == null) { 126 actionMap = getContextMenuSource().createActionMap(component); 127 } else { 128 // todo: replace actions with components? 129 } 130 return actionMap; 131 } 132 133 private ContextMenuSource getContextMenuSource() { 134 if (contextMenuSource == null) { 135 contextMenuSource = new TextContextMenuSource(); 136 } 137 return contextMenuSource; 138 } 139 140 141 142 }