package cern.gp.actions.support; import java.awt.FlowLayout; import javax.swing.Action; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JPanel; import org.openide.awt.Actions; import org.openide.awt.Mnemonics; import org.openide.util.ContextAwareAction; import org.openide.util.Utilities; import org.openide.util.actions.SystemAction; import org.openide.windows.TopComponent; /** * A few utility methods for Actions. This is partly an extension to the functionality * in openide.awt.Actions. * * @author Vito Baggiolini * @version $Revision: 1.2 $ $Date: 2006/09/25 08:52:36 $ */ public class ActionUtils { private static ImageIcon BLANK_ICON = null; /** do not instantiate */ private ActionUtils() { } /** * creates a JButton for the action class. This button takes its icon, description, shortcut etc from the * action class. It is enabled whenever the action is enabled. * @return a JButton */ public static JButton createJButton(Class actionClass) { return createJButton(SystemAction.get(actionClass)); } /** * creates a JButton for the action class that listens to Nodes in the specified TopComponent. This is useful, e.g. * when you want to place the JButton in a separate TopComponent (i.e. not in the Explorer TopComponent itself) * @param tc the TopComponent that contains the nodes (typically this is an Explorer) * @param actionClass an action supported by one or more of the nodes in the TopComponent * @return a JButton * @since 2.0.5 */ public static JButton createJButton(TopComponent tc, Class actionClass) { Action act = actionForComp(tc, actionClass); return createJButton(act); // if (act instanceof SystemAction) { // return createJButton(act); // } else { // String msg = (String) act.getValue(Action.NAME); // // String errMsg = "invalid action class, must inherit from SystemAction"; // System.err.println(errMsg); // JButton but = new JButton(msg); // but.setForeground(Color.red); // but.setToolTipText(errMsg); // return but; // } } /** * creates a JButton for the SystemAction itself. * You should not need to use this method, rather use {@link #createJButton(Class)} * If you find you need to use this action, please do not create actions yourself, * use the {@link SystemAction#get(java.lang.Class) or {@link #actionForComp(TopComponent, Class)} instead. * * @see #createJButton(Class) for more explanations * @return a JButton * @deprecated -- use {@link #createJButton(Action)} */ public static JButton createJButton(SystemAction act) { JButton but = new JButton(); // [PENDING] there is a problem when getIcon returns null: by default the icon is replaced with a text. // [PENDING] this produces buttons with twice the label. // [PENDING] to change this, one would have to work on the Actions.ButtonBridge class and especially // [PENDING] on the useTextIcons() method in there. // [PENDING] we have tried changing the icon in this method, but it doesn't work. We believeit gets updated // [PENDING] dynamically in the ButtonBridge class. Action swingAction = act; Actions.connect(but, swingAction); Mnemonics.setLocalizedText(but, act.getName()); return but; } /** * creates a JButton for the Action itself. * You should not need to use this method, rather use {@link #createJButton(Class)} * If you find you need to use this action, please do not create actions yourself, * use the {@link SystemAction#get(java.lang.Class) or {@link #actionForComp(TopComponent, Class)} instead. * * @see #createJButton(Class) for more explanations * @return a JButton * @since 2.0.5 */ public static JButton createJButton(Action act) { JButton but = new JButton(); // [PENDING] there is a problem when getIcon returns null: by default the icon is replaced with a text. // [PENDING] this produces buttons with twice the label. // [PENDING] to change this, one would have to work on the Actions.ButtonBridge class and especially // [PENDING] on the useTextIcons() method in there. // [PENDING] we have tried changing the icon in this method, but it doesn't work. We believeit gets updated // [PENDING] dynamically in the ButtonBridge class. Actions.connect(but, act); String label = "invalid"; if (act instanceof SystemAction) { label = ((SystemAction) act).getName(); } else { label = act.getValue(Action.NAME).toString(); } Mnemonics.setLocalizedText(but, label); return but; } /** * creates a JPanel with JButtons for the actions specified. The JPanel uses a FlowLayout. If you * don't like the JPanel, you can create the JPanel (or other component) yourself and use addJButtons * @return JPanel the panel containing the buttons */ public static JPanel createJButtonPanel(Class[] actionClasses) { JPanel pan = new JPanel(); pan.setLayout(new FlowLayout(FlowLayout.LEADING)); return (JPanel) addJButtons((JComponent) pan, actionClasses); } /** * creates a JPanel with JButtons for action classes that listen to Nodes in the specified TopComponent. * This is useful, e.g.when you want to place the Buttons in a separate TopComponent (i.e. not in the * Explorer TopComponent itself). * * @param tc the TopComponent that contains the nodes (typically this is an Explorer) * @param actionClasses actions supported by one or more of the nodes in the TopComponent * @return a JButton * @since 2.0.5 */ public static JPanel createJButtonPanel(TopComponent tc, Class[] actionClasses) { if (tc == null) { return createJButtonPanel(actionClasses); } JPanel pan = new JPanel(); pan.setLayout(new FlowLayout(FlowLayout.LEADING)); for (int ix = 0; ix < actionClasses.length; ix++) { pan.add(createJButton(tc, actionClasses[ix])); } return pan; } /** * Utility method, adds JButtons corresponding to the actionClasses to a JComponent * @return the JComponent passed as first paraameter, with the buttons added * @deprecated -- tell us (proj-gp-dev@cern.ch) if you really need it! */ public static JComponent addJButtons(JComponent comp, Class[] actionClasses) { for (int ix = 0; ix < actionClasses.length; ix++) { comp.add((JComponent) createJButton(actionClasses[ix])); } return comp; } // private static JComponent addJButtons(JComponent comp, Action[] actionClasses) { // for (int ix = 0; ix < actionClasses.length; ix++) { // comp.add((JComponent) createJButton(actionClasses[ix])); // } // return comp; // } /** * utility method, returns a blank icon, can be used if an existing icon shall be "hidden" */ public static ImageIcon getBlankIcon() { if (BLANK_ICON == null) { BLANK_ICON = new ImageIcon(Utilities.loadImage("org/openide/resources/actions/empty.gif")); } return BLANK_ICON; } /** * helper method, creates an action that is "connected" to the nodes inside a TopComponent. * This makes it possible to create Action Buttons that listen to nodes in an Explorer but * are located outside the Explorer's TopComponent * * @param tc the TopComponent (e.g. Explorer) to connect to * @param action the action class * @return the Context aware Action instance * @since 2.0.5 */ public static Action actionForComp(TopComponent tc, Class action) { Action a = SystemAction.get(action); return ((ContextAwareAction) a).createContextAwareInstance(tc.getLookup()); } }