TransformAlwaysToConditionallyEnabledAction

Transforming CallableSystemAction Into CookieAction

Contributed By Varun Nischal


This is based on the existing tutorial. That tutorial, lets you get started with the NetBeans Plugin-Development, by creating an Always Enabled (see CallableSystemAction), without using any Wizard and that too smoothly.

[[{TableOfContentsTitle=TableOfContents} | {TableOfContents title='Table of Contents'}]]

Pre-requisites


If you don’t have prior experience with NetBeans Platform, read that tutorial. That's a must! Now, after you have done that, you might like to explore a bit more. So, you should give the following a read as well(if you want you can skip it for a while and read it along with my tutorial),

This overview will quickly familiarize you with how NetBeans plug-in modules interact with the NetBeans infrastructure and with each other.

Now, you're ready for transformation. So, lets get started then!

What's CookieAction?


"An action dependent on the cookies of the selected nodes", as defined in the Javadocs! Exactly, so when you have done following transformation, you would see the action, but would be enabled, only when the node is selected, which supports particular Cookies. You will understand more, as you read further.


Getting Started


Here, we are going to transform an Action from one type to another, i.e. from CallableSystemAction TO CookieAction, sounds cool! Though, never tried! Well, here I am sharing with you another tips and tricks to make it possible, without using New File Type Wizard. We will make use of SayCheez.java, which was made in the reference tutorial.


Solution


So, to start with, remove the
CallableSystemAction
and let the class {SayCheez} inherit from CookieAction, like this;
public final class SayCheez extends CookieAction {
Now, don’t remove the already existing implementations of abstract methods of
CallableSystemAction
,

    @Override
    public void performAction() {
        //throw new UnsupportedOperationException("Not supported yet.");
        String msg = "I'm plugged in!";
        NotifyDescriptor d = new NotifyDescriptor.Message(msg, 
                NotifyDescriptor.INFORMATION_MESSAGE);
        DialogDisplayer.getDefault().notify(d);  
    }

    @Override
    public String getName() {
        //throw new UnsupportedOperationException("Not supported yet.");
        return NbBundle.getMessage(SayCheez.class, "CTL_SayCheez");
    }

    @Override
    public HelpCtx getHelpCtx() {
        //throw new UnsupportedOperationException("Not supported yet.");
        return HelpCtx.DEFAULT_HELP;
    }

    @Override      
    protected String iconResource() {  
        //Replace org/nvarun/tat with your path/to/icon  
        //see attachments to download icon24_TransformAlwaysToConditionallyEnabledAction.png  
        return "org/nvarun/tat/icon24_TransformAlwaysToConditionallyEnabledAction.png";  
    }      

    // Newly Added	
    @Override
    protected void initialize() {
        super.initialize();
        // see org.openide.util.actions.SystemAction.iconResource() Javadoc for more details
        putValue("noIconInMenu", Boolean.TRUE);
    }    
	
    // Newly Added	
    @Override
    protected boolean asynchronous() {
        return false;
    }
}

Now, just add the following 2 methods TO let the
class SayCheez
implement all the abstract methods defined by {CookieAction}.

@Override
protected Class<?>[] cookieClasses() {
return new Class[]<tt>$Interface}.class};
}

protected int mode() {
return CookieAction.{$mode};
}

Please note, that {$Interface} needs to be replaced by appropriate interface, i.e. it could be either of the following Cookie class(es), which are basically interfaces/abstract class(es);



1. Project
2. OpenCookie
3. EditCookie
4. EditorCookie
5. DataObject (Abstract Class, NOT an Interface)
I will be using
EditorCookie
for this transformation. Also, {$mode} needs to be replaced with either {MODE_EXACTLY_ONE}[[[1 | [1]] or MODE_ALL[[2].
1. User Selects One Node
2. User May Select Multiple Nodes
I will be using
MODE_EXACTLY_ONE
for this transformation.
MODE_EXACTLY_ONE
 
Action will be enabled if there is exactly one selected node and it supports the given cookies.
MODE_ALL
 
Action will be enabled if there are one or more selected nodes and all of them support the given cookies.
In our case, its
EditorCookie
! Now, alter the {performAction} method like this,

@Override
protected void performAction(Node[] activatedNodes) {
{$Interface} ref = activatedNodes[0].getLookup().lookup({$Interface}.class);
// TODO use {$Interface}
}

Here, ref is basically the reference to either the interface/class being made, which is being assigned a subclass reference, it could be of great use. Now, add your code for
DialogDisplayer
used in reference tutorial, in place of TODO comment.
        String msg = "I'm plugged in!";
        NotifyDescriptor d = new NotifyDescriptor.Message(msg, 
                NotifyDescriptor.INFORMATION_MESSAGE);
        DialogDisplayer.getDefault().notify(d); 

See, it was too easy! Anyways, the changes in XML Layer, which shall be done with respect to the change in the Action type, some of them are as follows and rest will be the mentioned in the next part of this series.

Tricks for Menu Item, Toolbar Button, Shortcut Keys

Trick #1

As you had made a Global Menu Item and Toolbar Button with
CallableSystemAction
, so no changes required, for transformation.

Trick #2

If you had made use of Shortcut Keys earlier, still no changes required.
Replace "
org-nvarun-tat
" with your package name, in which {SayCheez} resides.

Ready to Install/Reload

  • Not yet, firstly, recall if you saw some red underlines present in the code, Add relevant Module Dependencies...(see tutorial) to get rid of them, so finally your code looks like this;

Transformed Source Code


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

//package {$your-package};

import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.cookies.EditorCookie;
import org.openide.nodes.Node;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.util.actions.CookieAction;

/**
 *
 * @author Varun Nischal (nvarun@NetBeans.org)
 */
public class SayCheez extends CookieAction {

    @Override
    protected void performAction(Node[] activatedNodes) {        
        EditorCookie ref = activatedNodes[0].getLookup().lookup(EditorCookie.class);
        
        String msg = "I'm plugged in!";
	NotifyDescriptor d = new NotifyDescriptor.Message(msg, 
                NotifyDescriptor.INFORMATION_MESSAGE);
	DialogDisplayer.getDefault().notify(d); 
    }

    @Override
    public String getName() {
        return NbBundle.getMessage(SayCheez.class, "CTL_SayCheez");
    }

   @Override
    protected void initialize() {
        super.initialize();
        // see org.openide.util.actions.SystemAction.iconResource() Javadoc for more details
        putValue("noIconInMenu", Boolean.TRUE);
    }    

    @Override      
    protected String iconResource() {  
        //Replace org/nvarun/tat with your path/to/icon  
        //see attachments to download icon24_TransformAlwaysToConditionallyEnabledAction.png  
        return "org/nvarun/tat/icon24_TransformAlwaysToConditionallyEnabledAction.png";  
    }      

    public HelpCtx getHelpCtx() {
        return HelpCtx.DEFAULT_HELP;
    }

    @Override
    protected boolean asynchronous() {
        return false;
    }

    @Override
    protected int mode() {
        return CookieAction.MODE_EXACTLY_ONE;
    }

    @Override
    protected Class<?>[] cookieClasses() {
        return new Class[]{EditorCookie.class};
    }

}

Module's XML Layer

  • By the way, we missed one thing, what to do with the XML Layer. Don't worry, just see the following tips about your existing layer.xml, formed in reference tutorial. This is how it looks;
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
<filesystem>
    <folder name="Actions">
        <folder name="Tools">        
            <file name="org-nvarun-tat-SayCheez.instance"/>
        </folder>
    </folder>
  • Here, more tags are added, when you make this action, File Type OR Editor Context-sensitive;
 <!--Code To Be Added-->
  • Add relevant code, and you could also be ready for making it context-sensitive, however for time being, leave it as it is. I will tell you later how to add the code.
    <folder name="Menu">
        <folder name="Tools">
            <file name="org-nvarun-tat-SayCheez.shadow">
                <attr name="originalFile" stringvalue="Actions/Tools/org-nvarun-tat-SayCheez.instance"/>
                <attr name="position" intvalue="150"/>
            </file>
            <file name="org-nvarun-tat-separatorAfter.instance">
                <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
                <attr name="position" intvalue="175"/>
            </file>
            <file name="org-nvarun-tat-separatorBefore.instance">
                <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
                <attr name="position" intvalue="125"/>
            </file>
        </folder>
    </folder>
    <folder name="Toolbars">
        <folder name="Build">
            <file name="org-nvarun-tat-SayCheez.shadow">
                <attr name="originalFile" stringvalue="Actions/Tools/org-nvarun-tat-SayCheez.instance"/>
                <attr name="position" intvalue="325"/>
            </file>
        </folder>
    </folder>
</filesystem>

  • Replace "
    org-nvarun-tat
    " with your package name, in which {SayCheez} resides.

Installing and Using the Plug-in Module


Refer to the reference tutorial, on how to Install and use your plug-in module. If you liked it, feel free to give feedback, because this tutorial can only get better, if you actively participate in community.

Version Compatability


Works with NetBeans 6.0, 6.1 as said above. Try this out on your version, and make sure to notify us if anything goes wrong!

Thanks for following, enjoy and have fun!

Not logged in. Log in, Register

By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo