Java 7アプリケーションのメニューバーを(Mac上の)画面上部に表示させるにはどうしたらいいですか?また、正しく動作するキーボードショートカットもありますか?Java 7、Mac OSのキーボード対メニューの競合
私はSwingユーザーインターフェイスを持つJavaアプリケーションを持っています。多くのメニューには、キーボードに相当するものがあります。
システムに依存するものはほとんどありませんが、Mac OS Xではメニューバーは各ウィンドウではなく画面の上部に表示されるため、apple.laf.useScreenMenuBar
と設定します。
これはJava 6でもうまく動作しますが、先週のJava 7では、同じコードをコンパイルして実行するとキーボードショートカットでメニューアクションが2回実行されます。たとえば、添付のコードでは、コマンド⌘ + は、1つではなく2つのファイルダイアログを開きます。 (他のキーボードショートカットも2回動作しますが、ときどきウィンドウを移動しなければならないことがあります)
apple.laf.useScreenMenuBar
を設定しないとキーボードの問題が消えてしまいます。私のMacユーザーは不快に思うだろう。私は本当に適切な場所にメニューバーを持っていて、キーボードショートカットがうまくいきたいと思っています。
システム:上のMac OS 10.7.3(ライオン)後半-2010 MacBook Proの
のJava 7:
Javaのバージョン "1.7.0_04"
のJava(TM) SEランタイム環境(1.7.0_04-B21を構築)
は、Java HotSpot(TM)64ビットサーバーVM(23.0-B21、混合モードを構築する)
ジャVA 6:
Javaのバージョン "1.6.0_31"
のJava(TM)SE Runtime Environmentに
は、Java HotSpot(TM)64ビットサーバーVM(1.6.0_31-b04-415-11M3635を構築)(20.6-を構築私が見てきたb01-415、混合モード)
:
why apple.laf.useScreenMenuBar
should be gotten rid of の議論 - 私はそれのためにすべてをんだけど、起こっているようには見えません。
ディスカッションにつきましてnot using mrj.version
to detect that you're on a Mac - 有益ではありませんが、有望です。
添付コード(148行)の長さについて私のご迷惑をおかけしますが、私のSwingコードは非常に昔ながらです。特殊なフラグや設定をせずにコマンドラインからコンパイルして実行する必要があります。
import javax.swing.*;
import java.awt.Toolkit;
import java.awt.*;
import java.awt.event.*;
/**
* Shows that using the single screen-top menu bar on a Mac with Java 7
* causes keyboard shortcuts to act twice.
*
* To see the problem(on a Mac -- running OS X 10.7.3 in my case):
* 1) compile on either Java 6 or Java 7
* 2) run on Java 7
* 3) give the command-O shortcut
* You will see two file dialogues.
*
* -- J. Clarke, May 2012
*/
public class MenuBug {
private static void go(String[] args) {
// Comment out the following line to fix the problem;
// leave it active to see the problem.
// It doesn't help to ...
// ... put the line into a static block.
// ... put the line right after the setLookAndFeel call.
// ... put the line before after the setLookAndFeel call.
System.setProperty("apple.laf.useScreenMenuBar", "true");
MainWindow mainWindow = new MainWindow();
}
public static void main(final String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception e) {
JOptionPane.showMessageDialog(null,
e + " while loading look and feel",
"MenuBug error", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
go(args);
}
});
}
}
class MainWindow extends JFrame {
MainWindow() {
super ("Main Window");
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
addWindowListener (new WindowAdapter() {
public void windowClosing(WindowEvent e) {
dispose();
System.exit(0);
}
});
JMenuBar menuBar = createMenuBar();
setJMenuBar(menuBar);
pack();
setSize(350,300);
setVisible(true);
}
private JMenuBar createMenuBar() {
JMenuBar mBar = new JMenuBar();
JMenu menu = new JMenu("File");
String[] menuItemNames = new String[] {"New", "Open...", "Other"};
for (int i = 0; i < menuItemNames.length; i++) {
String miName = menuItemNames[i];
JMenuItem mi = new JMenuItem(miName);
mi.setActionCommand(miName);
linkMenuItemToAction(mi);
menu.add(mi);
}
mBar.add(menu);
return mBar;
}
/**
* Create an Action for menuItem, and make sure the action and the menu
* item know about each other; where appropriate, add keyboard equivalents.
* @param menuItem The menu item to be linked to an action.
*/
private void linkMenuItemToAction(JMenuItem menuItem) {
final int META_MASK =
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
Action a = null;
String miName = menuItem.getActionCommand();
if (miName.equals ("New")) {
a = new NewAction();
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N,
META_MASK));
}
else if (miName.equals ("Open...")) {
a = new OpenAction();
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O,
META_MASK));
}
else if (miName.equals ("Other")) {
a = new OtherAction();
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T,
META_MASK));
}
menuItem.setEnabled(a.isEnabled());
menuItem.addActionListener(a);
}
private class NewAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
new MainWindow();
}
}
private void makeDialog() {
String dialogTitle = "Please choose a file to open";
FileDialog fileDialog = new FileDialog(this, dialogTitle,
FileDialog.LOAD);
fileDialog.setVisible(true);
String fileName = fileDialog.getFile();
}
private class OpenAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
makeDialog();
}
}
private class OtherAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null,
"an example message",
"not really an error", JOptionPane.ERROR_MESSAGE);
}
}
}
(参考にしてくれたQwerty Bobに感謝します。私は本当にもっと見て、自分でやっていたはずです)私はこの質問を他の場所で聞いています。 –
更新:キーボードショートカットが機能するようになりましたが、メニューには表示されません!私は新しい7u7リリースを試している間にこれを発見しましたが、新しいバグはすでに7u6のために報告されているようです。(http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7186371) 私はMountain Lion(Mac OS X 10.8.1)にもアップデートしましたが、Lionシステムのクイックチェックでは、OSの変更ではなく、Javaリリースが原因であることがわかりました。 –
アップデート:メニューにキーボードショートカットの表示を含むJava 1.7u10がこれを修正しました。私は現在OS X 10.8.2を使用していますが、他のバージョンのものもOKです。 –