gpt4 book ai didi

Java JDialog 弄乱了 mac 上的 JMenuBar

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:31:46 24 4
gpt4 key购买 nike

我有一些关于 JMenuBar 的问题,我似乎无法弄清楚。

我将从问题的缩写开始:该程序由一个 JFrame、一个 JDialog 和一个 JMenuBar 组成。最初,您将看到一个顶部带有 JMenuBar 的 JFrame。但在某些时候,JDialog 会弹出,用户可以在其中填写一些文本字段。我遇到的问题是,一旦焦点转到 JDialog,JMenuBar 就会消失。我想要的是 JMenuBar 始终位于屏幕顶部,除非整个程序不在焦点中。这里有 2 个屏幕截图,在第一个屏幕截图中,选择了 JFrame,在另一个屏幕截图中,选择了 JDialog。

enter image description here

enter image description here

所以我真正想要的不是当焦点在 JFrame 上时只看到 JMenuBar,我想一直看到 JMenuBar。由于 JDialogs 不能像 JFrame 那样在顶部有 JMenuBar,因此我决定不使用多个 JMenuBar,而只使用应该始终可见的那个。

最后,我将给出尽可能小的(并且仍然有效)并且还包含问题的部分代码:

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JRootPane;
import javax.swing.KeyStroke;

/**
* @author Guus Leijsten
* @created Oct 27, 2012
*/
public class MenuBarProblem extends JFrame {
public MenuBarProblem() {
super("Frame");
this.setMinimumSize(new Dimension(270, 200));
this.setPreferredSize(new Dimension(800, 530));
this.setDefaultCloseOperation(EXIT_ON_CLOSE);

JRootPane root = this.getRootPane();
//Menu
JMenu fileMenu = new JMenu("File");
JMenuItem file_exit = new JMenuItem("Exit");
file_exit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
file_exit.setToolTipText("Exit application");
file_exit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
fileMenu.add(file_exit);

JMenuBar menu = new JMenuBar();
menu.add(fileMenu);
root.setJMenuBar(menu);

this.setVisible(true);

JDialog d = new JDialog(this, "Dialog");
d.setSize(200, 100);
d.setLocation(0, (int)root.getContentPane().getLocationOnScreen().getY());
d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
d.setVisible(true);
}

public static void main(String[] args) {
String os = System.getProperty("os.name").toLowerCase();
if(os.indexOf("mac") >= 0) {
System.setProperty("apple.laf.useScreenMenuBar", "true");
}
new MenuBarProblem();
}
}

老实说,我认为问题出在 JRootPane 部分。但我们会看到 ;)

有没有其他人遇到过这个问题并设法解决了它,或者有没有人想试一试?

提前致谢!


新增内容:

在下面的示例中,我将展示一个为游戏提供一些功能的版本。

这是我正在制作的程序: enter image description here第二张图片显示了右侧菜单未停靠的状态。 enter image description here显然,JMenuBar 应该仍然可见且可操作,因为没有它,程序的许多功能将被禁用。

在这一点上,我开始认为 JMenuBar 不可能在对话框(未停靠菜单)被取消停靠并专注于时保持可见。

我知道 JDialog 上的 JMenuBar 不能采用 mac osx 样式(屏幕顶部),所以是否有任何其他技术可以用于取消停靠,这确实给我一个 mac osx 样式的 JMenuBar?

最佳答案

解决这个问题的一个关键,双关语,是让 key binding分享一个共同点 menu action , 如下所示。请注意菜单项、对话框的内容和(否则是多余的)按钮如何全部使用相同的 Action 实例。一些附加说明:

  • 感谢使用 getMenuShortcutKeyMask()

  • Swing GUI 对象应该event dispatch thread (EDT) 上构造和操作.

  • 应在启动 EDT 之前设置系统属性。

  • 其几何形状已知后,使对话框的 setLocation() 相对于框架。

  • 一个常见的 Mac 习语使用以下谓词:

    if (System.getProperty("os.name").startsWith("Mac OS X") {…}
  • 另请参阅此 example .

  • 对于对话框本身的本地使用,还可以考虑 JToolBar .

MenuBarProblem with menu

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.KeyStroke;

/**
* @see https://stackoverflow.com/a/13100894/230513
*/
public class MenuBarProblem extends JFrame {

private static final int MASK =
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
private static final String exitName = "Exit";
private static final KeyStroke exitKey =
KeyStroke.getKeyStroke(KeyEvent.VK_W, MASK);
private final ExitAction exitAction = new ExitAction(exitName);

public MenuBarProblem() {
super("Frame");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);

JMenu fileMenu = new JMenu("File");
JMenuItem fileExit = new JMenuItem(exitAction);
fileMenu.add(fileExit);
JMenuBar menu = new JMenuBar();
menu.add(fileMenu);

JDialog d = new JDialog(this, "Dialog");
JPanel p = new JPanel();
p.getInputMap().put(exitKey, exitName);
p.getActionMap().put(exitName, exitAction);
p.add(new JButton(exitAction));
d.add(p);
d.pack();
d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);

this.setJMenuBar(menu);
this.pack();
this.setSize(new Dimension(320, 240));
this.setLocationByPlatform(true);
this.setVisible(true);
d.setLocation(this.getRootPane().getContentPane().getLocationOnScreen());
d.setVisible(true);
}

private static class ExitAction extends AbstractAction {


public ExitAction(String name) {
super(name);
this.putValue(Action.MNEMONIC_KEY, exitKey.getKeyCode());
this.putValue(Action.ACCELERATOR_KEY, exitKey);
}

@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}

public static void main(String[] args) {
System.setProperty("apple.laf.useScreenMenuBar", "true");
EventQueue.invokeLater(new Runnable() {

@Override
public void run() {
new MenuBarProblem();
}
});
}
}

关于Java JDialog 弄乱了 mac 上的 JMenuBar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13097787/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com