Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 禁用JMenu的所有项时禁用JMenu_Java_Swing_Jmenu - Fatal编程技术网

Java 禁用JMenu的所有项时禁用JMenu

Java 禁用JMenu的所有项时禁用JMenu,java,swing,jmenu,Java,Swing,Jmenu,当所有子项都被禁用时,我试图禁用JMenu。 我有一个菜单“添加新的”,在这个菜单中有两个菜单项:“文件”和“目录” 菜单项绑定到特定的操作,这些操作的状态我会更改,因此菜单项的状态也会更改 我试图实现的是,当“文件”和“目录”操作都被禁用时,“添加新”菜单被禁用,因此项目也被禁用 我试图重写isSelected()方法od JMenu,但它部分工作——它不显示项目。但是,菜单仍被绘制为活动(黑色字体而不是灰色) 关于如何实现这一点有什么想法吗 下面是一个复制这种情况的代码示例: public

当所有子项都被禁用时,我试图禁用JMenu。 我有一个菜单“添加新的”,在这个菜单中有两个菜单项:“文件”和“目录”

菜单项绑定到特定的操作,这些操作的状态我会更改,因此菜单项的状态也会更改

我试图实现的是,当“文件”和“目录”操作都被禁用时,“添加新”菜单被禁用,因此项目也被禁用

我试图重写isSelected()方法od JMenu,但它部分工作——它不显示项目。但是,菜单仍被绘制为活动(黑色字体而不是灰色)

关于如何实现这一点有什么想法吗

下面是一个复制这种情况的代码示例:

public static void main(String args[]) {
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() { 

            JFrame frame = new JFrame();
            JPopupMenu popup = new JPopupMenu();

            final Action actionBeep = new DefaultEditorKit.BeepAction();
            final Action actionPaste = new DefaultEditorKit.PasteAction();

            JMenu menu = new JMenu("Add");
            menu.add(new JMenuItem(actionBeep));
            menu.add(new JMenuItem(actionPaste));
            popup.add(menu);

            JTable table = new JTable(3, 3);

            table.setComponentPopupMenu(popup);
            table.addMouseListener(new MouseAdapter() {
               @Override
               public void mouseReleased(MouseEvent e) {
                   if(e.getClickCount() == 2) {
                       actionBeep.setEnabled(!actionBeep.isEnabled());
                       actionPaste.setEnabled(!actionPaste.isEnabled());
                   }
               }
            });

            frame.add(table);
            frame.pack();
            frame.setVisible(true);

        }
    });
}

一个容易忘记的事实是JMenu是一个抽象按钮,因此您可以为它设置一个操作。虽然从未调用该操作的actionPerformed,但其属性用于保持菜单相应属性的同步

因此,假设您的所有菜单都由(组)操作驱动,您可以定义一个包装器操作,将其自身的启用状态同步到这样一个组,然后将该包装器设置为菜单。这种方法的优点是您可以

  • 如果在主菜单和弹出窗口中应用相同的分组,则重复使用此类包装f.i
  • 建群树
包装器可能类似于:

/**
 * Empty Action with enabled state that's the OR'ed enabled of all contained actions.
 */
public static class OrEnabledEmptyAction extends AbstractAction {

    private List<Action> actions;

    public OrEnabledEmptyAction(Collection<Action> actions, String name) {
        super(name);
        this.actions = new ArrayList<>(actions);
        installEnabledListener();
        updateEnabled();
    }

    /**
     * Updates this Action's enabled state dependent on enabled of
     * contained actions.
     */
    private void updateEnabled() {
        boolean enabled = false;
        for (Action action : actions) {
            enabled |= action.isEnabled();
        }
        setEnabled(enabled);
    }

    /**
     * Installs a PropertyChangeListener which updates this Action's 
     * enabled state on notification of enabled of contained actions.
     */
    private void installEnabledListener() {
        PropertyChangeListener l = new PropertyChangeListener() {

            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                if ("enabled".equals(evt.getPropertyName()))
                    updateEnabled();
            }

        };
        for (Action action : actions) {
            action.addPropertyChangeListener(l);
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // does nothing, never called for a JMenu anyway
    }

}
/**
*已启用状态的空操作,该状态是所有包含操作的或已启用。
*/
公共静态类OrEnabledEmptyAction扩展了AbstractAction{
私人名单行动;
公共OrEnabledEmptyAction(集合操作、字符串名称){
超级(姓名);
this.actions=新的ArrayList(actions);
installEnabledListener();
updateEnabled();
}
/**
*根据已启用的更新此操作的已启用状态
*包含的操作。
*/
私有void updateEnabled(){
布尔启用=假;
for(操作:操作){
enabled |=action.isEnabled();
}
设置已启用(已启用);
}
/**
*安装更新此操作的属性的PropertyChangeListener
*通知已启用包含的操作时的已启用状态。
*/
私有void installeEnabledListener(){
PropertyChangeListener l=新的PropertyChangeListener(){
@凌驾
公共作废属性更改(属性更改事件evt){
if(“enabled”.equals(evt.getPropertyName()))
updateEnabled();
}
};
for(操作:操作){
action.addPropertyChangeListener(l);
}
}
@凌驾
已执行的公共无效操作(操作事件e){
//什么都不做,从来没有调用过JMenu
}
}
其用法(您的示例带有一个额外的主菜单以突出显示重复使用):

jpopplus popup=新建jpopplus();
最终操作beep=新建DefaultEditorKit.BeepAction();
最终操作粘贴=新建DefaultEditorKit.PasteAction();
最终列表操作=新建ArrayList();
actions.add(actionBeep);
actions.add(actionPaste);
JMenu菜单=新建JMenu();
//在弹出菜单中向菜单添加操作
for(操作:操作){
菜单。添加(操作);
}
//将菜单的操作设置为或已启用
menu.setAction(新建或启用清空操作(操作,“添加”));
弹出。添加(菜单);
JMenuBar=新的JMenuBar();
JMenu main menu=新建JMenu();
//将操作添加到菜单栏中的菜单
for(操作:操作){
主菜单。添加(操作);
}
//重复使用或行动
main menu.setAction(menu.getAction());
添加(主菜单);
frame.setJMenuBar(bar);
JTable table=新的JTable(3,3);
table.setComponentPopupMenu(弹出菜单);
//要查看效果,请仅更改一个操作的启用状态
//每释放
表.addMouseListener(新的MouseAdapter(){
整数指数;
@凌驾
公共无效MouseEvent(MouseEvent e){
如果(!SwingUtilities.isLeftMouseButton(e))
返回;
actions.get(index).setEnabled(!actions.get(index).isEnabled());
索引=(索引+1)%actions.size();
}
});

JMenu有一个setEnabled()函数。为什么不直接使用它呢?在我的设计中,它意味着一点额外的代码,但这确实是一个有效的解决方案。是的!这太棒了。我的设计基于动作,这非常适合它。谢谢
JPopupMenu popup = new JPopupMenu();

final Action actionBeep = new DefaultEditorKit.BeepAction();
final Action actionPaste = new DefaultEditorKit.PasteAction();

final List<Action> actions = new ArrayList<>();
actions.add(actionBeep);
actions.add(actionPaste);
JMenu menu = new JMenu();
// add actions to menu in popup
for (Action action : actions) {
    menu.add(action);
}
// sets the menu's action to the OR-Enabled
menu.setAction(new OrEnabledEmptyAction(actions, "Add"));
popup.add(menu);

JMenuBar bar = new JMenuBar();
JMenu mainMenu = new JMenu();
// add actions to menu in menuBar
for (Action action : actions) {
    mainMenu.add(action);
}
// re-use or-action
mainMenu.setAction(menu.getAction());
bar.add(mainMenu);
frame.setJMenuBar(bar);

JTable table = new JTable(3, 3);

table.setComponentPopupMenu(popup);
// for seeing the effect, change enabled state of only one action
// per released
table.addMouseListener(new MouseAdapter() {
    int index;
    @Override
    public void mouseReleased(MouseEvent e) {
        if (!SwingUtilities.isLeftMouseButton(e))
            return;
        actions.get(index).setEnabled(!actions.get(index).isEnabled());
        index = (index +1) % actions.size();
    }
});