http://blogs.oracle.com/geertjan/entry/code_for_rerun_dropdownbuttonfactory

——————————————————————————————————————————————————————————————————————

I made some serious progress with my redeploy plugin today. Since it was inspired by Gareth Uren, who liked this functionality in Eclipse and misses it in NetBeans IDE, I decided I should try to make it as similar as possible to how it works in Eclipse. So, here it is, no longer in a separate window, but using the NetBeans org.openide.awt.DropDownButtonFactory class:

Let's step through the code required for this functionality. First, I have extended org.apache.tools.ant.module.spi.AntLogger, which is exposed in META-INF/services, in a file called "org.apache.tools.ant.module.spi.AntLogger":

public class StoreDeployedApps extends org.apache.tools.ant.module.spi.AntLogger {

@Override
public boolean interestedInSession(AntSession session) {
return true;
}

@Override
public boolean interestedInAllScripts(AntSession session) {
return true;
}

@Override
public String[] interestedInTargets(AntSession session) {
return AntLogger.ALL_TARGETS;
}

@Override
public void targetStarted(AntEvent event) {
BufferedReader br = null;
try {
//Get the build-impl.xml:
File buildImplXML = event.getScriptLocation();
//From the build-impl.xml parent, get the project.xml:
File projectXML = new File(buildImplXML.getParentFile(), "project.xml");

String targetName = event.getTargetName();
String projectName = null;
String projectType = null;

//Read the Dom and figure out the project name and type,
//where the type is a string like "org.netbeans.modules.java.j2seproject":
InputSource source = new InputSource(new FileInputStream(projectXML));
org.w3c.dom.Document doc = XMLUtil.parse(source, false, false, null, null);
org.w3c.dom.NodeList nodeList = doc.getElementsByTagName("\*");
int length = nodeList.getLength();
for (int i = 0; i < length; i++) {
org.w3c.dom.Node currentNode = nodeList.item(i);
String nodeName = currentNode.getNodeName();
if ("name".equals(nodeName)){
projectName = currentNode.getTextContent();
}
if ("type".equals(nodeName)){
projectType = currentNode.getTextContent();
}
}

//If the target name is run, send the build-impl.xml, the project name,
//and the project type to our action class:
if (targetName.equals("run")) {
ListDeployedAppsAction.setProjectNames(buildImplXML, projectName, projectType);
}

} catch (SAXException ex) {
Exceptions.printStackTrace(ex);
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
} finally {
try {
br.close();
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
}
}

@Override
public void targetFinished(AntEvent event) {
}

}

And here's the action class, which is registered in the layer.xml file, just like any other action class that we want to be able to invoke from a toolbar button:

public class ListDeployedAppsAction extends CallableSystemAction {

private static JButton dropDownButton;
private static JPopupMenu popup;
static JMenu menu;

static void setProjectNames(File buildImplXML, String projectName, String projectType) {

Image icon = null;

if (projectType.equals("org.netbeans.modules.java.j2seproject")) {
icon = Utilities.loadImage("/org/netbeans/modules/java/j2seproject/ui/resources/j2seProject.png");
} else if (projectType.equals("org.netbeans.modules.web.project")) {
icon = Utilities.loadImage("/org/netbeans/modules/web/project/ui/resources/webProjectIcon.gif");
} else {
icon = Utilities.loadImage("/org/netbeans/modules/project/ui/resources/runProject.png");
}

ImageIcon image = new ImageIcon(icon);

menu = new JMenu();
JMenuItem subItemRun;

menu.setIcon(image);
menu.setText(projectName);

subItemRun = new JMenuItem("Run \\"" + projectName + "\\" again");
subItemRun.addActionListener(new RunActionListener(buildImplXML));
menu.add(subItemRun);

popup.add(menu);

}

static class RunActionListener implements ActionListener {

File file;

public RunActionListener(File file) {
this.file = file;
}

public void actionPerformed(ActionEvent e) {
try {
ActionUtils.runTarget(FileUtil.toFileObject(file), new String[]{"run"}, new Properties());
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
} catch (IllegalArgumentException ex) {
Exceptions.printStackTrace(ex);
}
}
}

@Override
public Component getToolbarPresenter() {

Image iconImage = Utilities.loadImage("/org/netbeans/modules/project/ui/resources/runProject.png");
ImageIcon icon = new ImageIcon(iconImage);

popup = new JPopupMenu();

dropDownButton = DropDownButtonFactory.createDropDownButton(
new ImageIcon(
new BufferedImage(32, 32, BufferedImage.TYPE_BYTE_GRAY)),
popup);

dropDownButton.setIcon(icon);

return dropDownButton;

}

@Override
public void performAction() {
}

@Override
public String getName() {
return "Deployed Apps";
}

@Override
public HelpCtx getHelpCtx() {
return null;
}

}

That's it. Next I need to add a submenu item for removing menu items. Maybe also a configuration dialog for tweaking the launch configurations that are registered in the list. By the way, in the process of moving my code from a window to a dropdown button factory, I was able to improve my code in several ways. Refactoring rocks. It really lets you look at your old code afresh.

 

posted on 2011-09-27 18:36  网络大豆  阅读(306)  评论(0编辑  收藏  举报