Presenter.Toolbar Meets @Action Annotations

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

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

Let's say you have a JPanel that you'd like to integrate into the NetBeans Platform toolbar. As an example, we imagine that this is the JPanel:

public class NextPrevJPanel extends JPanel {

    JButton nextButton = new JButton();
    JButton prevButton = new JButton();

    public NextPrevJPanel() {
        setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
        prevButton.setIcon(new ImageIcon(getClass().getResource("prev.png")));
        nextButton.setIcon(new ImageIcon(getClass().getResource("next.png")));
        prevButton.addActionListener(new PrevButtonActionListener());
        nextButton.addActionListener(new NextButtonActionListener());
        add(prevButton);
        add(nextButton);
    }

    private class NextButtonActionListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            //Simulate next action:
            JOptionPane.showMessageDialog(null, "Next");
        }
    }

    private class PrevButtonActionListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            //Simulate previous action:
            JOptionPane.showMessageDialog(null, "Previous");
        }
    }
    
}

 As you can see, we have a panel that provides navigation buttons. The standard NetBeans Platform approach to integrating the above panel into the toolbar would be to have you create, essentially, a dummy action. The action implements "Presenter.Toolbar" and returns the JPanel, which represents the dummy action in the toolbar:

@ActionID(category = "NextPrev", id = "org.demo.DummyAction")
@ActionRegistration(displayName = "")
@ActionReferences({
    @ActionReference(path = "Toolbars/File", position = 100)
})
public final class DummyAction extends AbstractAction implements Presenter.Toolbar {

    @Override
    public Component getToolbarPresenter() {
        return new NextPrevJPanel();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // Nothing to do here.
    }
    
}

It works, but it's not very nice. Aside from the fact that you have a meaningless "actionPerformed" in the code above, you also have a whole meaningless class, since it only exists to register the panel into the toolbar.

So, with NetBeans Platform 7.0, we can simply delete the above class. And then we rewrite our JPanel as follows:

public class NextPrevJPanel extends JPanel {

    @ActionID(category = "NextPrev", id = "org.demo.NextAction")
    @ActionRegistration(displayName = "", iconBase = "org/demo/next.png")
    @ActionReference(path = "Toolbars/NextPrev", position = 100)
    public static class NextButtonActionListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            //Simulate next action:
            JOptionPane.showMessageDialog(null, "Next");
        }
    }

    @ActionID(category = "NextPrev", id = "org.demo.PrevAction")
    @ActionRegistration(displayName = "", iconBase = "org/demo/prev.png")
    @ActionReference(path = "Toolbars/NextPrev", position = 200)
    public static class PrevButtonActionListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            //Simulate previous action:
            JOptionPane.showMessageDialog(null, "Previous");
        }
    }
    
}

Isn't that great? Action annotations on inner classes. It means you don't have to create a separate class file for each of your ActionListeners, which would be another approach to solving this problem.

In the code above, note that all the stuff about constructing/decorating/adding the JButtons is now gone. All we're left with is the actual logic in our JPanel. And we register that via the new @Action annotations into the toolbar, which means that the NetBeans Platform will create buttons for us. The NetBeans Platform is responsible for everything except the logic, which is our domain-level code anyway, while all the rest is just standard stuff that the NetBeans Platform will handle for us. Another very nice side effect is that the small icon/large icon switching works (thanks to our "iconBase" attribute), which is not the case when you use Presenter.Toolbar to put your panel into the toolbar. Only not-so-nice thing is that our inner classes are now static, since under the hood the action performed calls in inner classes are reached statically from the layer.

Finally, does this mean that Presenter.Toolbar (and friends) are now obsolete? I don't think so. For example, if you have a Google Toolbar, i.e., a panel containing a label and a text field, for example, you still need to put it into the toolbar somehow. In that particular scenario, you don't want the NetBeans Platform to create buttons for you and hence you will not use the approach outlined here.

原文地址:https://www.cnblogs.com/cuizhf/p/2189590.html