2012-10-27 1 views
3

У меня возникли проблемы с JMenuBar, и я не могу понять, как это понять.Java JDialog испортил JMenuBar на mac

Начну с искажения проблемы: программа состоит из JFrame, JDialog и JMenuBar. Первоначально вы увидите JFrame с JMenuBar в верхней части. Но в какой-то момент появится JDialog, где пользователь может заполнить некоторые текстовые поля. Проблема, с которой я столкнулась, заключается в том, что, как только основное внимание будет обращено на JDialog, JMenuBar исчезает. Я хочу, чтобы JMenuBar постоянно находился в верхней части экрана, за исключением того, что вся программа не находится в фокусе. Вот 2 скриншота, на первом снимке экрана выбран JFrame, а в другом - JDialog.

enter image description here

enter image description here

Так что я на самом деле хочу, вместо того, чтобы только видеть JMenuBar когда фокус находится на JFrame, я хочу, чтобы увидеть JMenuBar все время. Поскольку JDialogs не может иметь JMenuBar в верхней части, как у JFrame, я решил не иметь несколько JMenuBars, а только тот, который должен быть видимым все время.

В конце концов я дам часть кода, который является как можно (и до сих пор работает), а также содержит проблему:

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(); 
    } 
} 

Если я могу быть honoust, я думаю, что проблема лежит в части JRootPane. Но мы увидим;)

Неужели кто-нибудь еще столкнулся с этой проблемой и сумел решить эту проблему, или есть кто-нибудь, кто хочет дать ему шанс?

Заранее благодарен!


Добавлено содержание:

В следующем примере я покажу версию, которая дает некоторые функциональные возможности для игры.

Это программа, которую я делаю: enter image description here На втором изображении показано состояние, в котором правое меню отстыковано. enter image description here Очевидно, что JMenuBar должен быть видимым и работоспособным, так как без него многие функции программы будут отключены.

На данный момент я начинаю думать, что JMenuBar не может оставаться видимым, когда диалог (отстыкованное меню) отстыкован и сосредоточен.

Я знаю, что JMenuBar на JDialog не может быть в стиле mac osx (сверху экрана), поэтому есть ли какие-либо другие методы, которые я могу использовать для расстыковки, что дает мне стиль Mac OSX JMenuBar?

+0

не пользователь osx, что-то случилось, используя JMenuBar правильно, положите это на JFrame – mKorbel

+0

Что значит mKorbel? Мне нужно немного больше, чем это. Как правильно использовать JMenuBar? и положить что в JFrame? @mKorbel – Triplle

+0

[например] (http://docs.oracle.com/javase/tutorial/uiswing/components/menu.html#create), RootPane (мое мнение, поправьте меня, если я ошибаюсь) - это мост betweens Native OS и Инструмент Java Graphics Toolkit (AWT) – mKorbel

ответ

2

Один ключ к решению этой проблемы, предназначенный для каста, состоит в том, чтобы дать key binding общий общий номер menu action, как показано ниже. Обратите внимание, что элемент меню, содержимое вашего диалогового окна и кнопка (иначе лишняя) могут использовать один и тот же экземпляр Action. Несколько дополнительных примечаний:

  • Kudos для использования getMenuShortcutKeyMask().

  • Объекты поворота 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(); 
      } 
     }); 
    } 
} 
+0

батарея не включена – mKorbel

+0

Очень полезная информация alrady. Спасибо за эти советы. Я буду работать над этим в короткие сроки. Сначала нужно закончить экзамены;) – Triplle

+0

Я столкнулся с еще одной проблемой ... Когда я скопирую код, приведенный выше. У меня все еще нет меню, когда фокус находится в диалоговом окне. Странно то, что на скриншоте выше кода есть меню, даже когда фокус находится в диалоговом окне. Итак, любая идея, что вызывает эту проблему? – Triplle

0

Решено!

Использование JFrame с использованием setAlwaysOnTop (true) дает мне желаемый эффект от использования JMenuBar при изменении фокуса.

 Смежные вопросы

  • Нет связанных вопросов^_^