6 Stimmen

Erstellen eines Offscreen-Rahmens in Java (oder: wie vermeidet man ein leeres Menü auf einem Mac, wenn alle Anwendungsfenster geschlossen sind)?

Ich entwickle eine Mac-Anwendung und möchte, dass meine Menüleiste richtig aussieht.

Jeder Mac-Benutzer weiß, dass sich die Menüleiste im oberen Bildschirmmenü befinden sollte. Einstellung apple.laf.useScreenMenuBar a true in der Eigenschaftslistendatei werden die Frame-internen Menüleisten entfernt und die Menüleiste des aktuell fokussierten Fensters in das Bildschirmmenü verschoben.

Wenn jedoch alle Fenster ausgeblendet sind oder wenn es keine Fenster gibt, gibt es keine Menüleisten, die nach oben verschoben werden können, und Sie erhalten nur ein leeres Menü. Ich habe gehört, dass eine Lösung für dieses Problem darin besteht, ein Fenster außerhalb des Bildschirms zu erstellen, das fokussiert wird, wenn keine anderen Fenster aktiv sind. Der einzige Zweck dieses Fensters wäre sein Menü, so dass es ausgefüllt werden könnte, wenn die anderen Fenster nicht mehr da sind.

Allerdings habe ich jede Menge Probleme bekommen. Ich kann das Fenster scheinbar nicht vom Bildschirm wegbewegen, weil Macs nicht zulassen, dass man die Koordinaten auf eine Größe jenseits des Bildschirms einstellt; stattdessen wird es einfach abgeschnitten und am Rand positioniert. Gibt es noch etwas, was ich tun muss, um ein Fenster außerhalb des Bildschirms zu erstellen?

4voto

trashgod Punkte 199887

Sie sollten unbedingt die sehr hilfreiche Antwort von WizardOfOdds berücksichtigen. Verwendung von "Das Anwendungsmenü" und es ist einfach, ein minimales System einzurichten. Info.plist um loszulegen. Eine ausdauernde File ermöglicht es Ihrer Anwendung, ein neues Fenster zu öffnen, wenn andere geschlossen werden. Dieses 回答 Links zu einer einfachen ejemplo .

Obwohl Apples Leitlinien für die menschliche Schnittstelle ein hervorragender Anhaltspunkt dafür sind, was Ihre Nutzer erwarten, können Sie sicherlich mit dem Ansatz experimentieren, den Sie in Ihrer Frage vorgeschlagen haben. Sie könnten insbesondere Folgendes versuchen setLocation(Short.MIN_VALUE, Short.MIN_VALUE) auf das unsichtbare Fenster. Außerdem möchten Sie vielleicht auf eine WindowEvent in besonderer Weise, wenn es das Schließen des letzten sichtbaren Fensters signalisiert.

Nachtrag: Wenn Ihr Zuhörer sieht, dass das letzte sichtbare Fenster geschlossen wird, erstellen Sie ein neues, leeres Anwendungsfenster. Oder verschieben Sie das unsichtbare Fenster auf den Bildschirm und machen Sie es sichtbar, bis der Benutzer entscheidet, wie es weitergehen soll.

Nachtrag: Mac OS X verhindert hilfreicherweise ein sichtbar Fensterform aus dem Bildschirm verschoben wird, aber es ist einfach, eine unsichtbar Fenster in der Schwebe, wie unten dargestellt.

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 Stimmen

Wie der Fragesteller kann auch ich nicht erkennen, wie der von WizardOfOdds erwähnte Artikel helfen kann. Außerdem scheint der Fragesteller ein spezielles Problem zu haben: Ich kann das Fenster nicht vom Bildschirm wegbewegen, weil Macs es nicht zulassen, dass man die Koordinaten auf etwas anderes als die Größe des Bildschirms einstellt.

0 Stimmen

@Arjan: Danke für die Bearbeitung; wie haben Sie den gezielteren Link bekommen? Der Artikel verweist den Leser auf die Xcode-Beispiele in /Developer/Examples/Java . Ich habe ein Beispiel für das Verschieben eines Fensters außerhalb des Bildschirms hinzugefügt.

0 Stimmen

Ich habe gerade ein "Inspect Element" für die Überschrift in meinem Browser, und das ergab einen Anker: <a name="//apple_ref/doc/uid/TP40001909-211936" [..]> . (Einige andere Webseiten geben für jede Überschrift eine ID an, und IDs können auch für Anker verwendet werden). (Übrigens ein gutes Beispiel.)

1voto

Pete Punkte 41

Ich weiß, dass dieser Beitrag ziemlich alt ist, trotzdem hatte ich das gleiche Problem und habe die Lösung gefunden. Eigentlich ist es ganz einfach. Einfach no Fügen Sie die JMenuBar zu Ihrem Hauptrahmen hinzu, wenn Sie unter Mac OS X laufen, aber zu Ihrer Anwendung mit

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

Jetzt wird die Menüleiste immer noch angezeigt, auch wenn Sie die Sichtbarkeit aller Rahmen auf false setzen.

0voto

SyntaxT3rr0r Punkte 26957

Zunächst eine Anmerkung: Ihre Frage scheint in Wirklichkeit zu lauten: "Wie kann man ein Fenstermenü gemäß den Apple Human Interface Guidelines erstellen?" und nicht "einen Offscreen-Frame in Java erstellen", was wie ein monströser Hack aussieht.

Ich schlage vor, dass Sie Apples " Mac OS X-Integration für Java ", die unter " Menü Fenster ", zeigt offenbar genau, was Sie erreichen wollen:

Die Apple Human Interface Guidelines schlagen vor, dass alle Mac OS X-Programme ein Fenstermenü bereitstellen sollten, um den Überblick über alle derzeit geöffneten Fenster zu behalten. Ein Fenstermenü sollte eine Liste von Fenstern enthalten, mit einem Häkchen neben dem aktiven Fenster.

1 Stimmen

Hey... Ähm... hast du eigentlich meine Frage gelesen? Ich habe gefragt, wie man das Problem umgehen kann, dass das Bildschirmmenü verschwindet, wenn keine Fenster in Java geöffnet sind... Ich habe überhaupt nichts über die Apple Human Interface Guidelines gesagt.

0 Stimmen

Aus diesem Link: Es ist sehr zu empfehlen, die Menüs aus Windows zu entfernen und sie in die Menüleiste zu integrieren, aber dieser Ansatz emuliert nicht perfekt die ursprüngliche Erfahrung der Mac OS X-Menüs. In Mac OS X ist die Menüleiste eines nativen Programms immer sichtbar, wenn ein Programm das aktive Programm ist, unabhängig davon, ob gerade ein Fenster geöffnet ist oder nicht. In Java für Mac OS X sind die Menüs in der Menüleiste mit einem Rahmen der obersten Ebene verbunden, und die Menüs verschwinden, wenn der Rahmen geschlossen wird.

0 Stimmen

Arjan, ich weiß, das ist mein Problem, ich muss ein Fenster erstellen, das die Leute nicht sehen können, um das Menü zu halten.

0voto

Arjan Punkte 21308

Das ist zwar keine direkte Lösung, aber ich glaube, einige erstellen stattdessen ein 1-Pixel-Fenster. Das führt allerdings zu Beschwerden, wie bei Super User beschrieben: Chaotisches Verhalten eines toten Pixels auf meinem iMac 24" ...

0 Stimmen

Interessanter Artikel, aber ich verstehe den Zusammenhang nicht.

1 Stimmen

Ich denke, der Zusammenhang besteht darin, dass ein sichtbarer 1x1-Fenster-Hack für manche wie ein chaotischer toter Pixel aussehen kann, denn wenn er "sichtbar" ist, befindet er sich auf dem Bildschirm (im Gegensatz zu setVisible(false), das sich außerhalb des Bildschirms befinden kann).

0 Stimmen

Ah, ein Opossum-Pixel, das sich nur tot stellt :-)

0voto

Dies ist ein Kommentar zur Antwort von trashgod. Er ist zu groß, also muss ich ihn hierher verschieben >.<


Mehr Probleme!

Ich erhalte 2 Fehler:

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

Kann ich helfen? Ich bin noch nie auf so etwas gestoßen. Ich weiß nicht, was es bedeutet.

EDIT: Ich habe noch mehr Probleme! Das Offscreen-Fenster muss sichtbar sein, während es sich im Offscreen befindet, damit es ein Menü erzeugt, das in die Menüleiste des Bildschirms wechselt. Wenn ich den Code verwende

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

Ich erhalte die Ausgabe:

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

Er verschiebt sie zurück, sobald sie wieder sichtbar wird!

Ich habe lange gesucht und kann nichts finden.

0 Stimmen

Das ist das erwartete Verhalten. Ich habe meine Antwort bearbeitet und einen Link zu einem einfachen, plattformunabhängigen Beispiel hinzugefügt, das Ihnen helfen kann. Sie können auch Ihre Frage bearbeiten, um neue Erkenntnisse einzubeziehen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X