我在显示
JMenuBar
之前禁用 FileDialog
(因为当 FileDialog
可见时,菜单项仍然处于活动状态)使用 getJMenuBar().setEnabled(false)
,然后在 getJMenuBar().setEnabled(true)
关闭后调用 FileDialog
,但是菜单项在启用后不会变为活动状态 - 如果我更改为另一个应用程序并返回到我的应用程序,它们就会变为活动状态。我尝试致电 getJMenuBar().revalidate()
和/或 getJMenuBar().repaint()
但无济于事。
值得注意的是,我使用的是屏幕菜单栏,就像在 OS X 上一样。显示问题的示例代码:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MenuTest extends JFrame implements ActionListener {
private JMenuItem menuItemNew = new JMenuItem("New");
private JMenuItem menuItemOpen = new JMenuItem("Open");
private JMenuItem menuItemSave = new JMenuItem("Save");
private JMenu menuFile = new JMenu("File");
private JMenuBar menuBar = new JMenuBar();
public MenuTest() {
super("JMenu Test");
setSize(300, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
menuItemOpen.addActionListener(this);
menuFile.add(menuItemNew);
menuFile.add(menuItemOpen);
menuFile.add(menuItemSave);
menuBar.add(menuFile);
setJMenuBar(menuBar);
setVisible(true);
}
public void openFile() {
getJMenuBar().setEnabled(false);
FileDialog fd = new FileDialog(this, "Choose a file", FileDialog.LOAD);
fd.setVisible(true);
getJMenuBar().setEnabled(true);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == menuItemOpen) {
openFile();
}
}
public static void main(String[] arguements) {
System.setProperty("apple.laf.useScreenMenuBar", "true");
new MenuTest();
}
}
预先感谢您的意见/建议!
对我来说,我可以通过启用/禁用每个
JMenuItem
而不是菜单栏或菜单本身来解决问题。
我也在 EDT 上做了所有事情,以防万一这就是问题所在,但没有帮助。
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MenuTest implements ActionListener {
private JMenuItem menuItemNew = new JMenuItem("New");
private JMenuItem menuItemOpen = new JMenuItem("Open");
private JMenuItem menuItemSave = new JMenuItem("Save");
private JMenu menuFile = new JMenu("File");
private JMenuBar menuBar = new JMenuBar();
JFrame frame;
public MenuTest() {
}
public void buildGui(){
frame = new JFrame("JMenu Test");
frame.setSize(300, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
menuItemOpen.addActionListener(this);
menuFile.add(menuItemNew);
menuFile.add(menuItemOpen);
menuFile.add(menuItemSave);
menuBar.add(menuFile);
frame.setJMenuBar(menuBar);
frame.setVisible(true);
}
public void openFile() {
menuItemNew.setEnabled(false);
menuItemOpen.setEnabled(false);
menuItemSave.setEnabled(false);
FileDialog fd = new FileDialog(frame, "Choose a file", FileDialog.LOAD);
fd.setVisible(true);
menuItemNew.setEnabled(true);
menuItemOpen.setEnabled(true);
menuItemSave.setEnabled(true);
}
@Override
public void actionPerformed(ActionEvent e) {
openFile();
}
public static void main(String[] arguements) {
System.setProperty("apple.laf.useScreenMenuBar", "true");
EventQueue.invokeLater(()->{
new MenuTest().buildGui();
});
}
}
我可以确认 Matt 的答案在 macOS 上对我有用。但有些事情他没有提到,我会的,希望能节省一些时间。
我尝试仅禁用
JMenu
中的 JMenuBar
组件,这样我就只需编写一个 for
循环。我得到了与尝试暂时禁用 JMenuBar
时相同的行为。
JMenuBar b = getJMenuBar();
for (int i=0; i<b.getMenuCount(); i++)
b.getMenu(i).setEnabled(false); // then true later
仅暂时禁用
JMenuBar
,如果我执行以下操作之一,菜单项将再次工作:
如果事先已经禁用了
JMenuItem
,您不希望盲目禁用然后再启用它。
private ArrayList<JMenuItem> disabledMenuItems = new ArrayList<JMenuItem>();
private void disableAppMenuItems () {
JMenuBar b = getJMenuBar();
for (int i=0; i<b.getMenuCount(); i++) {
JMenu m = b.getMenu(i);
for (int j=0; j<m.getItemCount(); j++) {
JMenuItem mi = m.getItem(j);
if (mi != null && mi.isEnabled()) {
mi.setEnabled(false);
disabledMenuItems.add(mi);
}
}
}
}
private void undoDisableAppMenuItems () {
for (JMenuItem i : disabledMenuItems)
i.setEnabled(true);
disabledMenuItems.clear();
}
并非
JMenuItem
中的每个 JMenu
都可以禁用或启用(例如,JSeparator
组件)。这就是为什么上面的代码涵盖了 JMenuItem
为空的情况。