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

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

I was learning about org.openide.awt.DropDownButtonFactory yesterday, because of the cool Profiler drop-down buttons in the IDE's toolbar. I assumed they came from some private package and that I'd have to hack the code somehow but then discovered org.openide.awt.DropDownButtonFactory and the fact that it is publicly available and has been that way for a while already. I then came across Vadiraj's excellent blog entry on this topic and his reference to the FAQ How do I add a drop-down menu to a toolbar button?

Armed with all those fine resources, I made my first DropDownButton. Then I wanted to do something practical and thought of all the times where I've known the NetBeans API classes I needed but not the layer entries for registering them. And that I'd then go through a wizard for no other reason than that I wanted the layer entries. And at some point you've got all your dependencies set, so the wizard isn't helpful for you then either. The one and only reason you're going through a wizard is to get the layer entries, also because of some strangeness like the fact that sometimes packages are separated by a hyphen and other times by a dot and you can never remember which is which.

So I created a new plugin that presents you with a DropDownButton with items representing a few of the key elements in the layer file. When you select one, some basic stubs are created in the layer file, as you can see below, the illustration showing the exact tags generated for the selected item:

Several enhancements are imaginable, such as having the items loaded from the user directory and letting the user register new items there via the Options window. Also the tags could be smarter and detect the class names and so on. But for now, and also because my focus wasn't this functionality but learning about the DropDownButton, it does the job fine.

Here's all the code, which will be extremely useful if you like DropDownButtons too:

package org.netbeans.modules.layerreg;

import java.awt.Component;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.image.BufferedImage;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.text.JTextComponent;
import org.netbeans.api.editor.EditorRegistry;
import org.openide.awt.DropDownButtonFactory;
import org.openide.util.HelpCtx;
import org.openide.util.Utilities;
import org.openide.util.actions.CallableSystemAction;

public class LayerRegistrationAction extends CallableSystemAction {

private static JButton dropDownButton;
private static ButtonGroup buttonGroup;
private static JPopupMenu popup;
private MyMenuItemListener menuItemListener;

@Override
public Component getToolbarPresenter() {

Image iconImage = Utilities.loadImage("org/netbeans/modules/layerreg/icon.png");
ImageIcon icon = new ImageIcon(iconImage);

popup = new JPopupMenu();

menuItemListener = new MyMenuItemListener();

buttonGroup = new ButtonGroup();

String[] names = {"Actions", "Loaders", "Menu", "TopComponent", "Toolbars"};

for (int i = 0; i < names.length; i++) {
String name = names[i];
JCheckBoxMenuItem item = new JCheckBoxMenuItem(name);
item.setName(name);
item.addActionListener(menuItemListener);
buttonGroup.add(item);
popup.add(item);
}

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

dropDownButton.setIcon(icon);

dropDownButton.setToolTipText("Insert Layer Registration");

dropDownButton.addItemListener(new ItemListener() {

public void itemStateChanged(ItemEvent e) {
int state = e.getStateChange();
if (state == ItemEvent.SELECTED) {
/\*\* show popup menu on dropdown button at position: (0, height) \*/
popup.show(dropDownButton, 0, dropDownButton.getHeight());
}
}
});

popup.addPopupMenuListener(new PopupMenuListener() {

public void popupMenuCanceled(PopupMenuEvent e) {
dropDownButton.setSelected(false);
}

public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
dropDownButton.setSelected(false);
}

public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
}
});

return dropDownButton;

}

private class MyMenuItemListener implements ActionListener {

public void actionPerformed(ActionEvent ev) {

JMenuItem item = (JMenuItem) ev.getSource();

String desiredInsertion = item.getName();

JTextComponent editor = EditorRegistry.lastFocusedComponent();

if (desiredInsertion.equals("Actions")) {
editor.replaceSelection(ACTIONS);
} else if (desiredInsertion.equals("Loaders")) {
editor.replaceSelection(LOADERS);
} else if (desiredInsertion.equals("Menu")) {
editor.replaceSelection(MENU);
} else if (desiredInsertion.equals("Toolbars")) {
editor.replaceSelection(TOOLBARS);
} else if (desiredInsertion.equals("TopComponent")) {
editor.replaceSelection(TOPCOMPONENT);
}

}
}
String ACTIONS =
"<folder name=\\"Actions\\">\\n" +
" <folder name=\\"MyCategory\\">\\n" +
" <file name=\\"org-bla-bla-bla-MyOneAction.instance\\"/>\\n" +
" <file name=\\"org-bla-bla-bla-MyTwoAction.instance\\"/>\\n" +
" </folder>\\n" +
" <folder name=\\"MyOtherCategory\\">\\n" +
" <file name=\\"org-bla-bla-bla-MyOtherAction.instance\\"/>\\n" +
" </folder>\\n" +
"</folder>\\n";

String MENU =
"<folder name=\\"Menu\\">\\n" +
" <folder name=\\"MyMenu\\">\\n" +
" <file name=\\"MyAction.shadow\\">\\n" +
" <attr name=\\"originalFile\\" stringvalue=\\"Actions/MyCategory/org-bla-bla-bla-MyAction.instance\\"/>\\n" +
" </file>\\n" +
" </folder>\\n" +
"</folder>\\n";

String TOOLBARS =
"<folder name=\\"Toolbars\\">\\n" +
" <folder name=\\"MyToolbar\\">\\n" +
" <attr name=\\"SystemFileSystem.localizingBundle\\" stringvalue=\\"org.bla.bla.Bundle\\"/>\\n" +
" <file name=\\"org-bla-bla-bla-MyAction.instance\\">\\n" +
" <attr name=\\"SystemFileSystem.localizingBundle\\" stringvalue=\\"org.bla.bla.Bundle\\"/>\\n" +
" <attr name=\\"position\\" intvalue=\\"400\\"/>\\n" +
" </file>\\n" +
" </folder>\\n" +
"</folder>\\n";

String LOADERS =
"<folder name=\\"Loaders\\">\\n" +
" <folder name=\\"text\\">\\n" +
" <folder name=\\"x-mime\\">\\n" +
" <folder name=\\"Actions\\">\\n" +
" <file name=\\"org-openide-actions-CopyAction.instance\\">\\n" +
" <attr name=\\"position\\" intvalue=\\"500\\"/>\\n" +
" </file>\\n" +
" </folder>\\n" +
" </folder>\\n" +
" </folder>\\n" +
"</folder>\\n";

String TOPCOMPONENT =
"<folder name=\\"Windows2\\">\\n" +
" <folder name=\\"Components\\">\\n" +
" <file name=\\"MyTopComponent.settings\\" url=\\"MyTopComponentSettings.xml\\"/>\\n" +
" </folder>\\n" +
" <folder name=\\"Modes\\">\\n" +
" <folder name=\\"MyMode:-editor-or-explorer-or-properties-etc\\">\\n" +
" <file name=\\"MyTopComponent.wstcref\\" url=\\"MyTopComponentWstcref.xml\\"/>\\n" +
" </folder>\\n" +
" </folder>\\n" +
"</folder>\\n";

//Unused:
@Override
public void performAction() {
}

//Unused:
public String getName() {
return "";
}

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

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

}
 

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