Probleme mit com.apple.eawt.ApplicationAdapter

xanadoo

Erfahrenes Mitglied
Hallo zusammen

Ich habe bei einer Swing-Application ein Problem unter Mac OSX.
Und zwar nutze ich unter Mac eine Klasse, welche den com.apple.eawt.ApplicationAdapter erweitert.

Dieser hat die Methode
Code:
public void handleOpenFile(ApplicationEvent ev)

An einer anderen Stelle im Programm versuche ich folgendermasen eine Datei zu öffen:
Code:
ProcessBuilder pb = new ProcessBuilder("open", path);
pb.start();

In der Regel geht dies auch ohne Probleme, jedoch gibt es gewisse Dateitypen welche nun versucht werden über diese "handleOpenFile" Methode zu öffnen.
Das Problem ist, dass ich über diese Methode wieder
Code:
ProcessBuilder pb = new ProcessBuilder("open", path);
pb.start();
aufgerufe und ich somit in einem Endlos Loop bin...

Weiss jemand wie entschieden wird welche Methoden vom ProcessBuilder aufgerufen werden, bzw. ich verhindern kann, dass gewisse Dateitypen in der handleOpenFile-Methode vom ApplicationAdaper landen?

Wäre dankbar für jeden Tipp.
 
Hallo xanadoo,

du könntest einfach prüfen, ob der Dateityp, mit dem handleOpenFile() aufgerufen wurde, einem der "gewissen" Dateitypen entspricht. Sprich, du legst eine Liste an und prüfst ob der Wert darin enthalten ist.
Das wäre die Lösung auf der Seite deiner Applikation. Vielleicht gibt es auch etwas OS-spezifisches, aber da muss dir jemand anderes helfen ;)
 
Aber diese Prüfung würde ich ja dann in der Methode handleOpenFile machen...
Das Problem ist, dass ich gar nicht darin landen dürfte.
Ausser es gibt einen anderen / besseren weg eine Datei mit dem dazugehörenden Standardprogramm zu öffenen weder:
Code:
ProcessBuilder pb = new ProcessBuilder("open", path);
pb.start();
 
Da du dich offenbar unter Swing herumtreibst, wäre der Standardweg wohl
Java:
java.awt.Desktop.getDesktop().open(path);
siehe Java-Doku zu Desktop.open(File)

Btw. ist der com.apple.eawt.ApplicationAdapter deprecated.
Die offizielle Alternative wäre com.apple.eawt.Application (da gibt es auch ein paar deprecated Methoden, davon aber nicht abschrecken lassen).

Das sehe dann in etwa so aus:
Java:
com.apple.eawt.Application.getApplication().setOpenFileHandler(
        new com.apple.eawt.OpenFileshandler() {
            public void openFiles(com.apple.eawt.AppEvent.OpenFilesEvent event) {
                List<File> files = event.getFiles();
                if (files != null) {
                    for (File singleFile : files) {
                        if (isEligibleFile(singleFile)) {
                            openFile(singleFile);
                        }
                        // TODO Fehlermeldung: die Datei hat kein passendes Format
                    }
                }
            }
        });

Die Prüfung, ob du diese Datei selbst öffnen möchtest, muss in diesem EventHandler passieren.
Schließlich sind das die Dateien, die der Benutzer ausdrücklich (über Mac OS X) deinem Programm übergeben hat.
Um die Endlosschleife zu vermeiden, darf hier idealerweise kein fremdes Programm aufgerufen werden. Alternativ könntest du eine Fehlermeldung anzeigen, die besagt, dass du das Format selbst nicht magst, aber du bietest (per separatem Knopfdruck) an, das hinterlegte Standard-Programm zu öffnen.

Was du in deinem eigenen Datei-Menü unter einem Punkt "Datei Öffnen" treibst ist wieder eine andere Sache. Dort kannst du tatsächlich auf Desktop.open() zurückgreifen.

PS: die Entsprechung unter SWT fände sich hier: Program.launch()
 
Zuletzt bearbeitet:
Vielen Dank für die Antwort.

Es handelt sich um eine bestehende Applikation, welche auch auf OSX 10.4 laufen muss!
Für dieses OSX gibt es kein Java 6 -> Kein Desktop.
Aber versucht hatte ich dies auch schon aber ich lande am Schluss trotzdem im "handleOpenFile()".

Wie ich in der handleOpenFile bzw. openFiles Methode prüfe ob es sich um ein File handelt welches ich selbst öffnen will ist mir schon klar, das Problem ist ja das ich es nicht selbst öffnen will, sondern dass es das Standard Programm öffnen soll.
Die Dateien wurden eben nicht meinem Programm übergeben oder zugeteilt, sondern einem anderen!
Und genau darum verstehe ich ja nicht, wieso mein Programm meint, dass es diese Datei selbst öffnen soll.

Mal zur Veranschaulichung:

Von diesem Programm gibt es jedes Jahr eine neue Version, jede Version hat seinen eigenen Dokumententyp.
In der aktuellen Programmversion gibt es nun eine Liste aller Files der letzten 10 Programmversionen. Wenn nun eines dieser Files selektiert wird, dann soll dieses mit der dazugehörenden Programmversion geöffnet werden.

Wenn ich dies in einer Dummy-Applikation ohne den ApplikationAdapter mache, dann geht dies auch mit allen 10 Dokumenten Typen (da es dann natürlich keine handleOpenFile Methode gibt).
 
Mal zur Veranschaulichung:

Von diesem Programm gibt es jedes Jahr eine neue Version, jede Version hat seinen eigenen Dokumententyp.
In der aktuellen Programmversion gibt es nun eine Liste aller Files der letzten 10 Programmversionen. Wenn nun eines dieser Files selektiert wird, dann soll dieses mit der dazugehörenden Programmversion geöffnet werden.

So ganz verstehe ich das noch nicht. Hat der Nutzer dann alle 10 Programmversionen jeweils als separate Apps nebeneinander liegen?
Und wie drücken sich die einzelnen Dokumenttypen aus? Jedes Mal mit einer neuen Datei-Endung?
Eine Datei-Endung kann nur einem Standard-Programm zugeordnet werden. Wenn deine neueste Programm-Version von sich behauptet, dass es mit allen 10 Dokumenttypen umgehen kann, dann landet der Aufruf auch nur in dessen handleOpenFiles()-Methode.

zum Beispiel:
Im Falle wenn Office würde es mir beispielsweise wenig bringen LibreOffice, OpenOffice und MS Office nebeneinander zu installieren. Alle drei behaupten, dass sie sowohl .doc als auch .docx öffnen können. Bei beiden Endungen habe ich zum Beispiel LibreOffice als Standard-Programm hinterlegt. Wie soll ich dann in der LibreOffice handleOpenFiles()-Methode dann das MS Office aufrufen können? Ich bin doch selbst das eingetragene Standard-Programm...

Die natürlichste Variante für deine Anwendung wäre folglich, dass es selbst auch die 9 Vorgänger-Dokumenttypen selbst öffnen kann, wenn es schon behauptet das zu können...
Gegebenenfalls musst du beim Zusammensetzen deines App-Bundles der neuesten Version die Dokumenttypen-Zuordnung für die alten Dateien bewusst weglassen?
 
Die Dokomuententypen haben unterschiedliche Dateiendungen, welche auch nur einem Programm zugeordnet sind.
Wenn ich eine solche Datei per Doppelklick öffne, dann wird auch das richtige Standard-Programm gestartet, das OS wüsste also eigentlich, welches Programm zu verwenden ist.

Dass die Applikation alle Dateien selbst öffnen kann ist (in meinem Fall) keine Alternative, da das Programm sonst viel zu gross würde.

Und meine Frage ist ja eben gerade, wieso meine Applikation trotzdem meint, auch das Standard-Progamm der letzten 9 Dokumententypen zu sein und wie/wo ich dies konfigurieren kann.
 
Zuletzt bearbeitet:
Womöglich musst du dir deinen Build-Prozess (eventuell Ant?) näher anschauen.
Ich nutze beispielsweise den JarBundler für das Verpacken meiner Java-Anwendung in eine .app und gebe dort mittels des documenttype-Tags die Datei-Endungen mit, von denen ich behaupte, dass mein Programm sie öffnen kann.
siehe dazu hier

Vielleicht stehen dort bei deinen neuen Programmen immer noch die alten Dateiendungen mit drin?
 
Zurück