【问题标题】:How to create dynamic menus in a NetBeans plugin?如何在 NetBeans 插件中创建动态菜单?
【发布时间】:2016-05-10 20:56:46
【问题描述】:

我正在开发一个需要使用“动态”菜单的 NetBeans 插件,因为目前必须在一个专用于某个菜单项及其操作的类中进行硬编码。但是我希望允许用户通过插件提供的 UI 能够更改菜单项的值(它们的作用 - 这将在 main 方法中处理变量,我不允许用户编写主要方法本身的代码 - 它们被称为什么以及它们相关的键盘快捷键)以及添加和删除菜单项。我的插件可能会从文件中读取这些首选项,理想情况下只有一个类可以创建所有这些动态菜单项,其值在首选项文件中定义。

我知道有一种方法可以做到这一点,但我能找到的唯一真实信息是 this threadthe bugzilla page 它链接到的目前似乎已关闭,所以这对我没有帮助... 那么,究竟如何才能使用动态菜单项制作动态菜单呢?

我有 NetBeans 8.1 版和 JDK8。此外,当我说“动态菜单项”或类似内容时,我指的是从菜单中提供给您的实际选项(无论插件在那里做什么,在我的情况下,它会在何时将某些数据复制到剪贴板单击这些选项之一)。

【问题讨论】:

    标签: java netbeans dynamic plugins development-environment


    【解决方案1】:

    我在我的 netbeans RCP 应用程序中使用动态菜单。以下是我用于将动态菜单项添加到右键菜单、工具栏、菜单栏的一般格式...

    import java.awt.event.ActionEvent;
    import java.util.ArrayList;
    import java.util.List;
    import javax.swing.AbstractAction;
    import javax.swing.Action;
    import javax.swing.JComponent;
    import javax.swing.JMenu;
    import javax.swing.JMenuItem;
    import javax.swing.JPopupMenu;
    import javax.swing.JSeparator;
    import org.openide.awt.ActionID;
    import org.openide.awt.ActionReference;
    import org.openide.awt.ActionReferences;
    import org.openide.awt.ActionRegistration;
    import org.openide.awt.Actions;
    import org.openide.awt.DynamicMenuContent;
    import org.openide.util.actions.Presenter;
    
    /* Register your dynamic action using annotations (perferred over layer.xml entries)
    @ActionID(id = "ExampleDynamicMenu", category = "Edit")
    @ActionRegistration(lazy = false, displayName = "ExampleDynamicMenu")
    @ActionReferences({
        @ActionReference(path = "Loaders/folder/any/Actions", position = 666),
        @ActionReference(path = "Loaders/content/unknown/Actions", position = 666),
        @ActionReference(path = "Loaders/text/xml/Actions", position = 666),
        @ActionReference(path = "Projects/Actions", position = 666),
        @ActionReference(path = "Editors/TabActions", position = 666)
    })
    */
    public class ExampleDynamicMenu extends AbstractAction implements DynamicMenuContent, Presenter.Popup {
    
        @Override
        public JMenuItem getPopupPresenter() {
            JMenu menu = new JMenu(this);
            JComponent[] menuItems = createMenu();
            for (JComponent item : menuItems) {
                menu.add(item);
            }
            return menu;
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
            // does nothing, this is a popup menu
        }
    
        @Override
        public JComponent[] getMenuPresenters() {
            return createMenu();
        }
    
        @Override
        public JComponent[] synchMenuPresenters(JComponent[] items) {
            return createMenu();
        }
    
        private JComponent[] createMenu() {
            List<JComponent> items = new ArrayList<>(20);
    
            //TODO: Load the list of actions stored in the preferences, and for each action add a menu-item to the dynamic menu.
            // Note: You preferences can simply store the Action's category and id; then you can always get the action instances using
            //    Action action = Actions.forID(category_string, id_string);
            List<Action> actionsList = YOUR_PREFERENCES_GETTER.getActions(); //You have to figure out how to store and retrieve user's preferred actions list yourself :)
            for (Action action : actionsList) {
                if (action == null) { //Assume null means add a separator
                    if (items.size() > 0 && !(items.get(items.size() - 1) instanceof JSeparator)) { //Only add separators after actions.
                        items.add(new JPopupMenu.Separator());
                    }
                } else { //Convert action to menu item, and build your dynamic menu
                    items.add(toMenuItem(action));
                }
            }
            return items.toArray(new JComponent[items.size()]);
        }
    
        /**
         * Creates a menu item from an action.
         *
         * @param action an action
         * @return JMenuItem
         */
        private static JMenuItem toMenuItem(Action action) {
            JMenuItem item;
            if (action instanceof Presenter.Menu) {
                item = ((Presenter.Menu) action).getMenuPresenter();
            } else if (action instanceof Presenter.Popup) {
                item = ((Presenter.Popup) action).getPopupPresenter();
            } else {
                item = new JMenuItem();
                Actions.connect(item, action, false);
            }
            return item;
        }
    }
    

    【讨论】:

    • 我看到代码经常提到“弹出窗口”,我需要的唯一弹出窗口将是首选项面板,但我可能会单独执行此操作,所以我应该将演示者等更改为“菜单”或“弹出”是什么意思,目前在那里做什么?
    • 对不起,我究竟应该用什么替换 Loaders/folder/any/Actions,例如,我必须以什么格式向它提供 List 以及偏好的获取器?
    猜你喜欢
    • 2021-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-12
    • 2015-04-08
    • 1970-01-01
    相关资源
    最近更新 更多