站内搜索: 请输入搜索关键词

当前页面: 开发资料首页Netbeans 专题NetBeans Palette API Tutorial

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.

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.

Downloads

You are going to need for this tutorial

Creating the module

  1. Choose File > New Project. Under Categories, select NetBeans Plug-in Modules. Under projects, select Module Project and click Next.
  2. In the Name and Location panel, type palette-demo in Project Name. Set the the Project Location and Project Folder to whatever folder you fancy. Select the Standalone Modulde radio button and select the Set as Main Project checkbox. Click Next.
  3. In the Basic Module Configuration panel, set the Code Name Base to com.example.palette (or your preffered package name) and the Module Display Name to Palette Demo. Press Finish.

Creating a window

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.

  1. In the Projects window, select the Palette Demo (this is not necessary if Palette Demo is your only project open).
  2. Choose File > New File... .Under Categories, select NetBeans Module Development, then Window Component under File Types. Click Next.
  3. In the Basic Settings panel, select editor for Window Position. Click Next.
  4. In the Name, Icon and Location panel, type Drawing. Click Finish.

The DrawingTopComponent should open in the GUI Editor and you should have some new generated XML and Java files.

The TopComponent

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.

Adding a palette

In order to use the Palette API you'll have to declare a dependency for your module.
  1. Right-click the Palette Demo > Properties.
  2. Under the Libraries category click Add... . Select then Core - Component Palette and Nodes API. Click Ok.

A Palette contains one or more categories with items. First you'll have to define a new item.

  1. Right-click the project, select New -> File/Folder... Choose XML under Categories then XML Document under File Types. Click Browse... and select src/com/example/palette (Click Select Folder). Click Next.
  2. In the Name and Location panel, type simple-item for the File Name. Click Next.
  3. In the Select Document Type choose DTD-Constrained Document. Click Next.
  4. In the DTD Options, choose from the list for DTD Public ID -//NetBeans//Editor Palette Item 1.0//EN. Select editor_palette_item for the Document Root. Click Finish.

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.

More items

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.

Link it to the TopComponent

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).

  1. PaletteFactory.createPalette takes care of the creation part. It just needs the palette name (meaning the folder declared in the layer.xml and the actions for the palette). Since we don't need any actions right now we'll just create a dummy anonymous inner class.
        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
  2. We add the PaletteController in the Lookup of the TopComponent. We modify the DrawingTopComponent constructor to accept an InstanceLookup and we add a new no-arg constructor:
       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.

But what does it do ?

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.

Icons

The palette requires two versions of each icon for the palette item. A 16x16 pixel and a 32x32 version.

  1. Take 2 icons (the 16 and the 32 pixel icons) and add them to your project (this seems amazingly complicated; just use your favorite file manager to copy the icons in src/com/example/palette). Name the two files configure-16.png and configure-32.png.
  2. Edit the simple-item.xml file to configure the palette item with the new icon. The file should look like:
    <!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>
    

Text

  1. We change the simple-item.xml file some more and add text description
    <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.

  2. Since we make a reference in the simple-item.xml to the Bundle, we must edit it to add the new keys. Open the Bundle.properties file and add the keys:
    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:

Palette item class

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:

  1. Add a new class (File > New File... > Java Classes category > Java Class) with the name MyPaletteItem. It should look like this:
    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;
        }  
    }
    
  2. Configure the palette items with the new class. palette-item.xml should be now:
    <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>
    

Partial summary

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.

Next

What we need now is a way to:

Selected element in the Palette

The Palette API allows us to place a listener for changes. Thus we find out the selected object.

  1. First, we add the UI Utilities API to the library (Right-click on Palette Demo > Properties > Libraries > Add.. and select UI Utilities API). It's not mandatory - that is, you may add the listener without it - but it's nice to show messages in the status bar.
  2. We edit the DrawingTopComponent constructor to place our listener:
        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).

Drag and drop

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.

Some fun

  1. Open the DrawingTopComponent in Design mode, right-click the design window, select Layout and click Null Layout.
  2. Open it now in Source mode, and modify the drop method:
                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.



Versioning

  1. 26 February 2006 - Initial version

Notes

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