2010-02-02 7 views
6

Я делаю приложение для Mac, и я хочу, чтобы панель меню выглядела правильно.Создание внеэкранного фрейма в Java (или: как избежать пустого меню на Mac, когда все окна приложений закрыты)?

Любой пользователь Mac знает, что строка меню должна находиться в главном меню экрана. Установка apple.laf.useScreenMenuBar на true в файле списка свойств избавляется от строк в рамке меню и перемещает строку меню текущего сфокусированного окна в экранное меню.

Однако, когда все окна скрыты или когда нет окон, нет никаких строк меню, чтобы перейти к началу, и вы просто получаете пустое меню. Я слышал, что решение заключается в создании окна, которое фокусируется, когда нет других. Единственной целью этого было бы его меню, чтобы оно могло заполниться, когда другие ушли.

Однако у меня возникало множество проблем. Я не могу отобразить окно с экрана, потому что Mac не позволит вам установить координаты на что-то за размером экрана; он просто отсекает его и позиционирует его на краю. Есть ли что-то еще, что я должен сделать, чтобы создать внеэкранное окно?

ответ

4

Вы должны обязательно рассмотреть очень полезный ответ WizardOfOdds. Правильное использование "The Application Menu" поможет, и для начала легко установить минимальный Info.plist. Постоянное меню File позволит вашему приложению открыть новое окно, когда другие будут закрыты. Это answer ссылки на простой example.

Несмотря на то, что Human Interface Guidelines от Apple - отличное руководство для ваших пользователей, вы можете, конечно, поэкспериментировать с тем подходом, который вы предложили в своем вопросе. В частности, вы можете попробовать setLocation(Short.MIN_VALUE, Short.MIN_VALUE) в невидимом окне. Кроме того, вы можете захотеть ответить на WindowEvent каким-то особым образом, если он сигнализирует о закрытии последнего видимого окна.

Приложение: Когда ваш слушатель увидит последнее видимое окно рядом, создайте новое пустое окно приложения. Кроме того, переместите невидимое окно на экран и сделайте его видимым, пока пользователь не решит, как действовать.

Приложение: Mac OS X услужливо предотвращает форму окна видны перемещаемым закадровый, но это легко положить окно невидимым в подвешенном состоянии, как показано на рисунке ниже.

import java.awt.BorderLayout; 
import java.awt.EventQueue; 
import java.awt.event.ItemEvent; 
import java.awt.event.ItemListener; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JToggleButton; 

public class FrameTest extends JFrame { 

    private static FrameTest marco; 
    private static FrameTest polo; 

    private static class MyPanel extends JPanel { 

     public MyPanel() { 
      super(true); 
      final JToggleButton b = new JToggleButton("Test"); 
      b.addItemListener(new ItemListener() { 
       @Override 
       public void itemStateChanged(ItemEvent e) { 
        if (b.isSelected()) { 
         polo.setLocation(100, 100); 
         polo.setVisible(true); 
        } 
        else { 
         polo.setVisible(false); 
         polo.setLocation(Short.MIN_VALUE, Short.MIN_VALUE); 
        } 
       } 
      }); 
      this.add(b); 
     } 
    } 

    public FrameTest(String title) { 
     super(title); 
     this.setLayout(new BorderLayout()); 
     this.add(new MyPanel()); 
     this.pack(); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

    public static void main(final String[] args) { 

     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       marco = new FrameTest("Marco"); 
       marco.setLocationRelativeTo(null); 
       marco.setVisible(true); 
       polo = new FrameTest("Polo"); 
       polo.setLocation(Short.MIN_VALUE, Short.MIN_VALUE); 
      } 
     }); 
    } 
} 
+0

Как и вопрос, я не понимаю, как может помочь ссылка на статью WizardOfOdds. Кроме того, у вопросника, похоже, есть конкретная проблема: * Я не могу отобразить окно с экрана, потому что Mac не позволит вам установить координаты на что-то за пределами размера экрана * – Arjan

+0

@Arjan: спасибо за редактирование; как вы получили более целенаправленную ссылку? Статья ссылается на примеры Xcode в «/ Developer/Examples/Java». Я добавил пример перемещения окна за кадром. – trashgod

0

Первое примечание: ваш вопрос кажется действительно «как иметь меню« Окно »в соответствии с Руководством пользователя Apple, а не« создание заставки на Java », что кажется чудовищным взломом.

Я предлагаю проверить Apple «Mac OS X Integration for Java», который, в соответствии с «Window menu», показывает, по-видимому, именно то, что вы пытаетесь достичь:

компании Apple Руководство Human Interface предполагает, что все приложения Mac OS X должны обеспечить Окно меню для отслеживания всех открытых в настоящее время окон. Меню «Окно» должно содержать список окон с галочкой рядом с активным окном.

+1

Эй ... Ум ... Вы действительно прочитали мой вопрос? Я как-то спросил, как обойти проблему, когда экранное меню исчезает, когда в Java нет открытых окон ... Я ничего не сказал о Руководствах по человеческому интерфейсу Apple. – 2010-02-02 20:02:31

+0

С этой ссылкой: * Снятие меню из окон и помещение их в панель меню очень рекомендуется, но этот подход не совсем подражает собственному опыту меню Mac OS X. В Mac OS X панель меню собственного приложения всегда отображается, когда приложение является активным приложением, независимо от того, открыты ли какие-либо окна. В Java для Mac OS X меню в строке меню связаны с фреймом верхнего уровня, и меню исчезнет, ​​если рамка закрывается. * – Arjan

+0

+1 за то, что вы призвали к рассмотрению принципов интерфейса! – trashgod

0

Неправильное решение, но я думаю, что некоторые создают вместо него 1-пиксельное окно. Это дает жалобы, как описано в Super User: Chaotic behavior of a dead pixel on my iMac 24" ...

+0

Интересная статья, но мне не хватает связи. – trashgod

+1

Я думаю, что соединение заключается в том, что при создании видимого окна с окнами 1x1, а для некоторых это может выглядеть как хаотический мертвый пиксель, потому что, если он «видимый», он отображается на экране (в отличие от setVisible (false), который может быть расположен вне экрана). – SyntaxT3rr0r

+0

Ах, пиксель опоссума, просто играющий мертвый :-) – trashgod

0

Это комментарий к отвечу trashgod. Он слишком велик, поэтому я должен переместить его здесь>.<


Больше проблем!

Я получаю 2 ошибки:

line 23: The method itemStateChanged(ItemEvent) of type new ItemListener(){} must override a superclass method

line 50:The method run() of type new Runnable(){} must override a superclass method

Любая помощь? Я никогда не сталкивался с этим раньше. Я не знаю, что это значит.

EDIT: У меня больше проблем! Мне нужно, чтобы экранное окно было видимым, пока оно выключено, чтобы оно создавало меню для перемещения в панель меню экрана. Когда я использую код

offScreen = new JFrame("WTF?! You can see me?"); 
offScreen.setSize(400,300); 
offScreen.setLocation(0, java.awt.Toolkit.getDefaultToolkit().getScreenSize().height+50); 
System.out.println(offScreen.getLocation()); 
offScreen.setVisible(true); 
System.out.println(offScreen.getLocation()); 

Я получаю выход:

java.awt.Point[x=0,y=1100] 
java.awt.Point[x=0,y=961] 

Он перемещает его обратно, как только он снова становится видимым!

Я искал веки, и я ничего не могу найти.

+0

Это ожидаемое поведение. Я отредактировал свой ответ и добавил ссылку на простой, независимый от платформы пример, который может вам помочь. Кроме того, вы можете изменить свой вопрос, чтобы включить новые результаты. – trashgod

1

Я знаю, что это сообщение довольно старое, во всяком случае, у меня была та же проблема и нашел решение. На самом деле все довольно просто. Просто не добавить JMenuBar к главной раме при работе на Mac OS X, но приложения с помощью

com.apple.eawt.Application.getApplication().setDefaultMenuBar(menuBar);

Теперь MenuBar все еще отображается, даже если вы установите видимость всех фрейма к ложным.

+0

Работал отлично, спасибо! –

+0

Однако он не работает в Java 7 ... http://java.net/jira/browse/MACOSX_PORT-775 –

0

Этот код работает в Java 7:

if(isMac) { 
    //This creates an invisible frame so that we always have a menu bar visible 
    JFrame menuFrame = new JFrame(); 
    menuFrame.setUndecorated(true); 
    menuFrame.setJMenuBar(defaultMenuBar); 
    AWTUtilities.setWindowOpaque(menuFrame, false); 
    menuFrame.setBounds(0,0,1,1); 
    menuFrame.setVisible(true); 
} 

Просто позвоните это, прежде чем открывать какие-либо другие окна, и он будет оставаться в фоновом режиме и автоматически становится сосредоточенным окно, когда другие закрыты. Вы все равно можете использовать метод com.apple.eawt.Application.getApplication(). SetDefaultMenuBar (menuBar) в своем приложении, чтобы вам не нужно было называть setJMenuBar() для каждого JFrame.