How do I add a drop-down menu to a toolbar button?

Apache NetBeans Wiki Index

Note: These pages are being reviewed.

To add a drop-down menu to a component in a toolbar, you can either extend CallableSystemAction and override public Component getToolbarPresenter(), or implement javax.swing.Action or any subclass thereof, and implement Presenter.Toolbar which defines that method.

You might want to create a JToggleButton, and when the button is pressed, show a JPopupMenu. (Also try org.openide.awt.DropDownButtonFactory.)

Example:

public class PickDrawingLineAction extends CallableSystemAction {
    private static JToggleButton toggleButton;
    private static ButtonGroup buttonGroup;
    private static JPopupMenu popup;
    private MyMenuItemListener menuItemListener;

    List handledCharts;

    public void performAction() {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                toggleButton.setSelected(true);
            }
        });

    }

    public String getName() {
        return "Pick Drawing Line";
    }

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

    protected boolean asynchronous() {
        return false;
    }

    public Component getToolbarPresenter() {
        Image iconImage = Utilities.loadImage(
            "org/blogtrader/platform/core/netbeans/resources/drawingLine.png");
        ImageIcon icon = new ImageIcon(iconImage);

        toggleButton = new JToggleButton();

        toggleButton.setIcon(icon);
        toggleButton.setToolTipText("Pick Drawing Line");

        popup = new JPopupMenu();
        menuItemListener = new MyMenuItemListener();

        handledCharts = PersistenceManager.getDefalut()
                        .getAllAvailableHandledChart();

        buttonGroup = new ButtonGroup();

        for (AbstractHandledChart handledChart : handledCharts) {
            JRadioButtonMenuItem item =
                new JRadioButtonMenuItem(handledChart.toString());
            item.addActionListener(menuItemListener);
            buttonGroup.add(item);
            popup.add(item);
        }

        toggleButton.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                int state = e.getStateChange();
                if (state == ItemEvent.SELECTED) {
                    /** show popup menu on toggleButton at position: (0, height) */
                    popup.show(toggleButton, 0, toggleButton.getHeight());
                }
            }
        });

        popup.addPopupMenuListener(new PopupMenuListener() {
            public void popupMenuCanceled(PopupMenuEvent e) {
                toggleButton.setSelected(false);
            }
            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
                toggleButton.setSelected(false);
            }
            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
            }
        });

        return toggleButton;
    }

    private class MyMenuItemListener implements ActionListener {
        public void actionPerformed(ActionEvent ev) {
            JMenuItem item = (JMenuItem)ev.getSource();
            String selectedStr = item.getText();

            AnalysisChartTopComponent analysisTc =
                AnalysisChartTopComponent.getSelected();

            if (analysisTc == null) {
                return;
            }

            AbstractChartViewContainer viewContainer =
                analysisTc.getSelectedViewContainer();
            AbstractChartView masterView = viewContainer.getMasterView();
            if (!(masterView instanceof WithDrawingPart)) {
                return;
            }

            DrawingPart drawingPart =
                ((WithDrawingPart)masterView).getCurrentDrawing();

            if (drawingPart == null) {
                JOptionPane.showMessageDialog(
                        WindowManager.getDefault().getMainWindow(),
                        "Please add a layer firstly to pick line type",
                        "Pick line type",
                        JOptionPane.OK_OPTION,
                        null);
                return;
            }

            AbstractHandledChart selectedHandledChart = null;

            for (AbstractHandledChart handledChart : handledCharts) {
                if (handledChart.toString().equalsIgnoreCase(selectedStr)) {
                    selectedHandledChart = handledChart;
                    break;
                }
            }

            if (selectedHandledChart == null) {
                return;
            }

            AbstractHandledChart handledChart =
                selectedHandledChart.createNewInstance();
            handledChart.setPart(drawingPart);
            drawingPart.setHandledChart(handledChart);

            Series masterSeries = viewContainer.getMasterSeries();
            DrawingDescriptor description =
                viewContainer.getDescriptors().findDrawingDescriptor(
                    drawingPart.getLayerName(),
                    masterSeries.getUnit(),
                    masterSeries.getNUnits());

            if (description != null) {
                Node stockNode = analysisTc.getActivatedNodes()[0];
                Node node =
                    stockNode.getChildren()
                        .findChild(DescriptorGroupNode.DRAWINGS)
                        .getChildren().findChild(description.getDisplayName());

                if (node != null) {
                    ViewAction action =
                        (ViewAction)node.getLookup().lookup(ViewAction.class);
                    assert action != null :
                        "view action of this layer's node is null!";
                    action.view();
                }
            } else {
                /** best effort, should not happen */
                viewContainer.setCursorCrossVisible(false);
                drawingPart.setActived(true);

                SwitchHideShowDrawingLineAction.updateToolbar(viewContainer);
            }

        }
    }

}