Best Practice JFrame Objekt allgemein zugänglich machen

kruemelkeksfan

Aktives Mitglied
Hallo Leute,

seit ich mit GUI-Programmierung angefangen habe habe ich ein Problem, das ich nie richtig lösen konnte:

Immer wenn ich sehe, dass ein Stück Code problematisch ist, also eine Exception auslösen oder sonst dem Programm zur Laufzeit schaden könnte, lasse ich ein kleines Fenster mit einer Fehlermeldung ausgeben, die spezifiziert, wo welches Problem aufgetreten ist. Wenn diese Fehlermeldung (eine Klasse, die JFrame erweitert) "konstruiert" wird, soll sie das Hauptfenster via "dispose ()" schließen. Mein Problem ist, dass der Konstruktor dafür eine Referenz auf das Hauptfenster braucht. Da der Konstruktor von nahezu überall aus aufgerufen werden kann, heißt das in der Praxis, dass fast jedes Objekt in meinen GUI-Programmen eine Referenz auf das Fenster benötigt und als Instanzvariable speichern muss.

Diese Lösung kommt mir ziemlich hakig vor und ich wollte mal Fragen, wie ihr das Problem lösen würdet? Ich suche einen Weg, eine Referenz auf das Hauptfenster in den Konstruktor der Fehlermeldung zu bekommen, ohne überall Referenzen auf selbes in Konstruktoren übergeben zu müssen oder eine ellenlange Kette von Gettern durch meine Klassenhierarchie zu legen, nur damit das Hauptfenster im Ernstfall geschlossen werden kann. Meine Konstruktor-Parameterlisten sind schon ohne solche Späße zum Bersten gefüllt :bahnhof:

LG Max
 
Ich verstehe den Sinn hinter deiner Konstruktion nicht aber ich denke, dass du dir dabei etwas gedacht hast, weshalb ich darauf nicht eingehen werde. Aber grundsätzlich sind Exceptions Dinge, die verhindert werden sollten und wenn sie doch mal fliegen sollten sie so schnell wie möglich behandelt werden, sodass der Nutzer so wenig Unannehmlichkeiten davon hat, wie möglich.

Ich würde das über einen EventMulticaster lösen (Events sind mMn sowieso eine geniale Erfindung).
Du erstellst eine Klasse ErrorOcurredEvent, die du von EventObject ableitest. Dieses Event enthält alles, was du dem Empfänger des Events gerne mitteilen würdest.
Du erstellst ein Interface ErrorOcurredEventListener, welches du von EventListener ableitest. Dieses Interface stellt nur eine Methode bereit: errorOcurred(ErrorOcurredEvent e). Dieses Interface wird von allen Klassen implementiert, denen du mitteilen möchtest, dass ein Fehler passiert ist.
Du erstellst eine Klasse EventMulticaster, welcher ErrorOcurredEventListener implementiert. Außerdem bietet er Methoden an um Listener hinzuzufügen und zu entfernen und natürlich ein Medium um diese zu speichern. Wird auf ihn errorOcurred aufgerufen, so ruft er errorOcurred auf alle gespeicherten Listener auf. Achte dabei darauf die zu behandelnde Referenz zu übergeben und nicht einfach eine Neue zu erzeugen. Jedes Objekt, bei dem ein Fehler auftreten könnte bekommt eine Referenz von EventMulticaster. Achte dabei darauf, dass nur eine Instanz von EventMulticaster existiert.
 
Ich verstehe den Sinn hinter deiner Konstruktion nicht aber ich denke, dass du dir dabei etwas gedacht hast, weshalb ich darauf nicht eingehen werde.

Du darfst meine Konstruktion ruhig kritisieren 🙂
Um das nochmal präziser zu erklären: Ich arbeite gerade an einer Klassenbibliothek, die ich für andere Projekte nutzen will. Die Fehler und Exceptions, die die Fehlermeldung auslösen sollen, beziehen sich zu 99% auf irgendwelche Fälle, wo die Bibliothek falsch verwendet wird. Beispielsweise, wenn der Pfad, der auf ein Bild verweisen soll nicht korrekt ist. Ich könnte alternativ natürlich auch eine Fehlermeldung auf der Konsole ausgeben lassen, das wäre viel einfacher. Allerdings wird es dann schwierig, wenn ich beim Testen etwas übersehe und einem Endanwender dann das Programm abschmiert. Es wäre u.U. ziemlich aufwendig einem Ottonormalverbraucher zu erklären, wie er das Programm auf der Konsole startet, damit er mir die Fehlermeldung durchgeben kann. Besser er kriegt ein handliches Fenster gezeigt, in dem steht: "Yo, es ist was schiefgelaufen. Dieser Mist hier funktioniert nicht." Dann kann der Benutzer mir eine Mail schicken und ich weiß was Sache ist.

Wenn ich dich richtig verstanden habe, soll ich, statt die Fehlermeldung direkt nach dem Auftreten des Fehlers zu kontruieren, den fehlerhaften Code ein Event auslösen lassen. Der EventListener kann dann darauf reagieren und die Fehlermeldung ausgeben. Die Idee klingt gut und scheint den Nagel auf den Kopf zu treffen. Leider habe ich selbst noch nie ein Event programmiert und habe nicht ganz verstanden, worauf du mit dem Multicaster hinaus willst? Was macht der? Das Event von der Quelle zum Listener weiterleiten?
 
Dann macht die Konstruktion doch mehr Sinn.

Genau das tut er. Dann braucht zwar jedes Objekt eine Referenz auf den Multicaster aber dafür behältst du den Überblick, wer auf was eine Referenz braucht und du kannst sehr leicht Events an mehr als nur ein Objekt weiterleiten.
Der Multicaster läuft in einem eigenen Thread, damit er den Auslösenden nicht lahmlegt. Dazu solltest du dich (wenn noch nicht geschehen) mit wait und notify auseinandersetzen.

Wie man Events programmiert steht im Internet besser, als ich es erklären könnte. Bei Problemen helfe ich trotzdem gerne 😉
 
Hm, aber dann habe ich ja im Prinzip nichts gekonnt 🙁
Wenn ich jetzt jedem Objekt eine Multicaster-Referenz mitgebe, statt einer JFrame-Referenz, ist das vielleicht sauberer und objektorientierter, aber mein Grundproblem, dass ich eben nach Möglichkeit gar nichts mitgeben will, wird nicht gelöst.
Ich werd vermutlich einfach System.out verwenden und hoffen, dass ich meine Klassen ordentlich verwende, damit ich gar nicht erst irgendwelche Fehlermeldungen auswerfen muss.
 
Du könntest alles in ein ErrorLog umleiten und wenn das Programm abstürzt anzeigen lassen, dass das ErrorLog an dich weitergeleitet werden soll. Ich glaube, dass geht mit Hooks.
 
Mir ist noch etwas eingefallen, für den Fall, dass Hooks bei Abstürzen nicht funktionieren:
Du erstellst ein Flag (Registry, eigene Dokumente, Programmordner etc.). Dieses Flag wird bei jedem Start gesetzt und bei jedem Beenden ggf. mit einem Hook zurückgesetzt.
Ist das Flag beim Start immer noch gesetzt, so ist das Programm abgestürzt oder wurde nicht ordnungsgemäß beendet (Task Manager) und du zeigst eine entsprechende Meldung an.
 
Hm, ich glaube du denkst ziemlich kompliziert 😀 Aber es ist eine super Idee eine Textdatei abzuspeichern. Dann könnte ich auch versuchen die Fehlermeldungen in der Textdatei abzuspeichern und das Programm normal mit System.exit (0) zu beenden. Danke für die Anregung 🙂
 

Zurück
Oben