通过 revalidate() 和 repaint() 更新 Swing 中的 JMenu 不起作用

Update JMenu in Swing via revalidate() and repaint() not working

在登录过程中,如果管理员正在登录我想启用名为Admin的JMenuItem。程序启动时,其可见性设置为 false。因此,当用户再次单击 Log In I 运行 JMenu 并尝试重新创建它时 Admin 现在设置为 true。这是我的初始化方法的代码,如果它检测到用户是管理员,则它是 运行。该方法位于应用程序使用的 JMenuBar class 中。

public void initialize() {

    file = new JMenu("File");
    file.setName("File Menu");
    file.addMouseListener(this);

    help = new JMenu("Help");
    help.setName("Help Menu");
    help.addMouseListener(this);

    login = new JMenu("Login");
    login.setName("Login Menu");
    login.addMouseListener(this);

    language = new JMenu("Language");
    language.setName("Language Menu");
    language.addMouseListener(this);

    admin = new JMenu("Admin");
    admin.setName("Admin Menu");
    if(LoginDialog.AdminLoggedIn) {
        admin.setEnabled(true);
    } else
        admin.setEnabled(false);
    admin.addMouseListener(this);   

    add(file);
    add(login);
    add(help);
    add(language);
    add(admin);

    this.revalidate();
    this.repaint();

}

谢谢。

我建议不要重新创建 JMenu,而是修改它,具体取决于程序的管理员状态。您可以为程序提供一个权限枚举,其中一个包含 REGULAR 和 ADMINISTRATOR(可能还有其他)字段,例如:

public enum Privileges {
    REGULAR("Regular"), ADMINISTRATOR("Administrator");
    private String text;
    private Privileges(String text) {
        this.text = text;
    }

    @Override
    public String toString() {
        return text;
    }
}

然后根据程序的权限状态更改 JMenu 的状态。另请注意:不要在菜单上使用 MouseListener,因为它们不符合菜单/菜单项/按钮的 enabled/disabled 状态。例如,这是我的小 MVCE 示例,它使用模型-视图-控制器结构(某种):

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.*;
import javax.swing.event.SwingPropertyChangeSupport;

@SuppressWarnings("serial")
public class MenuChanger extends JPanel {
    private CreateMenu createMenu = new CreateMenu();
    private MenuChngModel model = new MenuChngModel();
    private ButtonGroup buttonGroup = new ButtonGroup();

    public MenuChanger() {
        setPreferredSize(new Dimension(400, 300));
        model.addPropertyChangeListener(MenuChngModel.PRIVILEGES, new ModelListener());

        JPanel privilegesPanel = new JPanel();
        privilegesPanel.setLayout(new GridLayout(0, 1, 5, 5));
        privilegesPanel.setBorder(BorderFactory.createTitledBorder("Privileges"));

        for (final Privileges privileges : Privileges.values()) {
            JRadioButton rBtn = new JRadioButton(privileges.toString());
            if (privileges == Privileges.REGULAR) {
                rBtn.setSelected(true);
            }
            rBtn.addActionListener(e -> {
                createMenu.setPrivileges(privileges);
            });
            buttonGroup.add(rBtn);
            privilegesPanel.add(rBtn);
        }

        add(privilegesPanel);

    }

    public CreateMenu getCreateMenu() {
        return createMenu;
    }

    private class ModelListener implements PropertyChangeListener {
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            Privileges privileges = (Privileges) evt.getNewValue();
            createMenu.setPrivileges(privileges);
        }
    }

    private static void createAndShowGui() {
        MenuChanger mainPanel = new MenuChanger();

        JFrame frame = new JFrame("MenuChanger");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.setJMenuBar(mainPanel.getCreateMenu().getMenubar());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

class MenuChngModel {
    public static final String PRIVILEGES = "privileges";
    private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(this);
    private Privileges privileges = Privileges.REGULAR;

    public Privileges getPrivileges() {
        return privileges;
    }

    public void setPrivileges(Privileges privileges) {
        Privileges oldValue = this.privileges;
        Privileges newValue = privileges;
        this.privileges = privileges;
        pcSupport.firePropertyChange(PRIVILEGES, oldValue, newValue);
    }

    public void addPropertyChangeListener(PropertyChangeListener listener) {
        pcSupport.addPropertyChangeListener(listener);
    }

    public void removePropertyChangeListener(PropertyChangeListener listener) {
        pcSupport.removePropertyChangeListener(listener);
    }

    public void addPropertyChangeListener(String name, PropertyChangeListener listener) {
        pcSupport.addPropertyChangeListener(name, listener);
    }

    public void removePropertyChangeListener(String name, PropertyChangeListener listener) {
        pcSupport.removePropertyChangeListener(name, listener);
    }

}

enum Privileges {
    REGULAR("Regular"), ADMINISTRATOR("Administrator");
    private String text;
    private Privileges(String text) {
        this.text = text;
    }

    @Override
    public String toString() {
        return text;
    }
}

class CreateMenu {
    private JMenuBar menubar = new JMenuBar();
    private JMenu fileMenu = new JMenu("File");
    private JMenu adminMenu = new JMenu("Administrator");
    private JMenuItem fileMenuItem = new JMenuItem("File Menu Item");
    private JMenuItem adminFileMenuItem = new JMenuItem("Admin File Menu Item");


    public CreateMenu() {
        fileMenu.setMnemonic(KeyEvent.VK_F);
        adminMenu.setMnemonic(KeyEvent.VK_A);

        fileMenu.add(fileMenuItem);
        fileMenu.add(adminFileMenuItem);       
        adminMenu.add(new JMenuItem("Foo 1"));
        adminMenu.add(new JMenuItem("Foo 2"));
        adminFileMenuItem.setEnabled(false);
        adminMenu.setEnabled(false);
        menubar.add(fileMenu);
        menubar.add(adminMenu);
    }

    public void setPrivileges(Privileges privileges) {
        switch (privileges) {
        case REGULAR:
            adminMenu.setEnabled(false);
            adminFileMenuItem.setEnabled(false);
            break;
        case ADMINISTRATOR:
            adminMenu.setEnabled(true);
            adminFileMenuItem.setEnabled(true);
            break;

        default:
            break;
        }
    }

    public JMenuBar getMenubar() {
        return menubar;
    }

}