当前页面: 开发资料首页 → Netbeans 专题 → NetBeans Palette API Tutorial
摘要: This tutorial shows you how to use the Palette API and make a palette available for your TopComponent. You will also learn how to create a simple TopComponent using the wizard, how to display a status-bar message and a dialog. But all these other things are just so that you'll learn how to display a nice palette for your TopComponent, with icons, localized text and drag-and-drop support.
This tutorial shows you how to use the Palette API and make a palette available for your TopComponent. You will also learn how to create a simple TopComponent using the wizard, how to display a status-bar message and a dialog. But all these other things are just so that you'll learn how to display a nice palette for your TopComponent, with icons, localized text and drag-and-drop support.
You are going to need for this tutorial
As seen in the Palette API javadoc, you need to have an active TopComponent in order to see the palette. For help regarding TopComponents, please check some other NetBeans tutorials.
The DrawingTopComponent should open in the GUI Editor and you should have some new generated XML and Java files.
To see what you have managed so far, right-click the Palette Demo project and select Install/Reload in Target Platform. A build should start and a new NetBeans instance should run. In the new instance, select Window > Open Drawing Window. You should see an empty window with the name Drawing Window.
A Palette contains one or more categories with items. First you'll have to define a new item.
You should see this:
<?xml version="1.0" encoding="UTF-8"?> <!-- Document : simple-item.xml Created on : February 25, 2006, 12:57 AM Author : emi Description: Purpose of the document follows. --> <!DOCTYPE editor_palette_item PUBLIC '-//NetBeans//Editor Palette Item 1.0//EN' "http://www.netbeans.org/dtds/editor-palette-item-1_0.dtd"> <editor_palette_item> </editor_palette_item>
Make sure to add the missing part above.
We have now a barebone Palette Item. Open now the layer.xml file and add the following lines at the bottom, before </ filesystem >
<folder name="MyPalette"> <folder name="Category1"> <file name="PaletteItem_1.xml" url="simple-item.xml"/> </folder> <folder name="Category2"> <file name="PaletteItem_2.xml" url="simple-item.xml"/> </folder> </folder>
What did we do? We declared a folder called MyPalette (which will represent our palette) and added some inner folders. These will be the categories. The files inside the categories folders are the items. The items may have any names you want but note the url refers to the simple-item.xml.
In order to have more than one item, you'll need to create more XML files (like simple-item.xml) and refer them via url in the layer.xml file. The are ways of programatically adding new items, but you'll have to refer to the Palette API Javadoc for that.
But so far there is no link between our rudimentary palette and our TopComponent. The Palette API javadoc helps us here. We need to create a PaletteController then link it to the TopComponent (via Lookup).
private PaletteController initializePalette() { try { return PaletteFactory.createPalette( "MyPalette", new PaletteActions() { public Action[] getCustomCategoryActions(Lookup lookup) { return new Action[0]; } public Action[] getCustomItemActions(Lookup lookup) { return new Action[0]; } public Action[] getCustomPaletteActions() { return new Action[0]; } public Action[] getImportActions() { return new Action[0]; } public Action getPreferredAction(Lookup lookup) { return null; //TODO } }); } catch (IOException ex) { ex.printStackTrace(); } return null; }We add the initializePalette() method to the DrawingTopComponent class. Since there are going to be lots of import problems an Alt + Shift + F should help (Source > Fix Imports). When you are asked about the Action class, just select javax.swing.Action
private DrawingTopComponent(){ this(new InstanceContent()); } private DrawingTopComponent(InstanceContent content) { super( new AbstractLookup( content ) ); content.add( initializePalette() ); initComponents(); setName(NbBundle.getMessage(DrawingTopComponent.class, "CTL_DrawingTopComponent")); setToolTipText(NbBundle.getMessage(DrawingTopComponent.class, "HINT_DrawingTopComponent")); // setIcon(Utilities.loadImage(ICON_PATH, true)); }
Re-run the application (Right-click Palette Demo > Install/Reload in Target Platform). Select Window > Open Drawing Window should also show the palette.
So far our Palette Demo is quite simple. The palette isn't that nice, no icons and it also doesn't do anything.
First, let's add some icons for our palette items and localized text.
The palette requires two versions of each icon for the palette item. A 16x16 pixel and a 32x32 version.
<!DOCTYPE editor_palette_item PUBLIC '-//NetBeans//Editor Palette Item 1.0//EN' "http://www.netbeans.org/dtds/editor-palette-item-1_0.dtd"> <editor_palette_item> <icon16 urlvalue="com/example/palette/configure-16.png" /> <icon32 urlvalue="com/example/palette/configure-32.png" /> </editor_palette_item>
<editor_palette_item> <icon16 urlvalue="com/example/palette/configure-16.png" /> <icon32 urlvalue="com/example/palette/configure-32.png" /> <description localizing-bundle="com.example.palette.Bundle" display-name-key="Item_Name" tooltip-key="Item_Tooltip" /> </editor_palette_item>
Each text should be possible to localize, you define the bundle (localizing-bundle) and then define the display and tooltip key.
CTL_DrawingAction=Open Drawing Window CTL_DrawingTopComponent=Drawing Window HINT_DrawingTopComponent=This is a Drawing window OpenIDE-Module-Name=Palette Demo Item_Name=Item name Item_Tooltip=A tooltip
If you start the module in the platform, you should see the new icons and text:
Ok, if you looked at the messages in the output window, you would probably see some warnings about the bad XML format. Each palette item must have besides the icon and text an attached class. The class must implement ActiveEditorDrop (which assumes a text-only situation but works for non-text data also). The main part of this class is to be instantiated by the Palette when doing a drag and drop operation. Here it goes:
package com.example.palette; import javax.swing.text.JTextComponent; import org.openide.text.ActiveEditorDrop; public class MyPaletteItem implements ActiveEditorDrop{ public boolean handleTransfer(JTextComponent jTextComponent) { //IGNORE, we don't really care return true; } }
<editor_palette_item version='1.0'> <class name="com.example.palette.MyPaletteItem"/> <icon16 urlvalue="com/example/palette/configure-16.png" /> <icon32 urlvalue="com/example/palette/configure-32.png" /> <description localizing-bundle="com.example.palette.Bundle" display-name-key="Item_Name" tooltip-key="Item_Tooltip" /> </editor_palette_item>
So, in order to use the palette we must add to the Lookup of a TopComponent a PaletteController. When creating the PaletteController, we give to the PaletteFactory the name of a palette folder in the layer.xml.
The folder structure in the layer.xml is quite simple, with subfolders for categories and files for items. Each item must refer a standard XML file (with a specific Palette DTD). In the palette item XML we define the icons, the text (via bundle keys) and a corresponding class.
What we need now is a way to:
The Palette API allows us to place a listener for changes. Thus we find out the selected object.
private DrawingTopComponent(InstanceContent content) { super( new AbstractLookup( content ) ); final PaletteController controller= initializePalette(); content.add( controller ); controller.addPropertyChangeListener( new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { if( PaletteController.PROP_SELECTED_ITEM.equals( evt.getPropertyName() ) ) { Lookup selItem = controller.getSelectedItem(); if( null != selItem ) { ActiveEditorDrop selNode = (ActiveEditorDrop)selItem.lookup( ActiveEditorDrop.class ); if(null != selNode){ StatusDisplayer.getDefault().setStatusText("Selected "+selNode); } } } } }); initComponents(); setName(NbBundle.getMessage(DrawingTopComponent.class, "CTL_DrawingTopComponent")); setToolTipText(NbBundle.getMessage(DrawingTopComponent.class, "HINT_DrawingTopComponent")); // setIcon(Utilities.loadImage(ICON_PATH, true)); }Since there are going to be some import problems, a Source > Fix Imports is necessary.
We now have the basic mechanism for our basic Palette implementation. We just need to modify the listener method and do whatever we need (like change mouse cursor, do an action on next mouse click on our TopComponent, etc).
The Palette already takes care of the drag part, we just have to provide the drop. (Actually we could also customize the drag with some custom flavors. Better check the Palette API javadoc if you are in need of such things).
Since we are going to display a message dialog, you need to add the Dialogs API to the module dependencies (Right-click Palette Demo > Properties > Libraries > Add... > Dialogs API)
Modify the DrawingTopComponent and add the following code
private DrawingTopComponent(InstanceContent content) { super( new AbstractLookup( content ) ); final PaletteController controller= initializePalette(); content.add( controller ); controller.addPropertyChangeListener( XXX); // removed to save space setDropTarget(new DropTarget(this,new DropTargetListener() { public void dragEnter(DropTargetDragEvent dropTargetDragEvent) { } public void dragExit(DropTargetEvent dropTargetEvent) { } public void dragOver(DropTargetDragEvent dropTargetDragEvent) { } public void drop(DropTargetDropEvent dropTargetDropEvent) { NotifyDescriptor d =new NotifyDescriptor.Message("Drop", NotifyDescriptor.INFORMATION_MESSAGE); DialogDisplayer.getDefault().notify(d); } public void dropActionChanged(DropTargetDragEvent dropTargetDragEvent) { } })); //the rest removed to save space
That's all there is to it. Our drop method is invoked when necessary and we may use the Palette API for fun and profit !
Please note that in order to make drop work nicely you should comment the select code (at least the display of the dialog) since it would interfere with the drop.
public void drop(DropTargetDropEvent dropTargetDropEvent) { JButton j=new JButton("drop"); j.setBounds(dropTargetDropEvent.getLocation().x, dropTargetDropEvent.getLocation().y,100,20); add(j); validate(); repaint(); //accept drop dropTargetDropEvent.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); }
The code above adds a JButton on the coordinates of the drop.
Tutorial made by Emilian Bold (http://web.info.uvt.ro/~fierarul/typo3/)
The sample code has two icons from the Nuvola set, which is LGPL. Feel free to contact me, as LGPL requires, in
order to get the full set. Hopefully I'll replace those icons with some BSD ones.
↑返回目录
前一篇: NetBeans Mobility Pack 5.0 Quick Start Guide
后一篇: NetBeans Partner Programs