Die naive Art des Schreibens eines Menüs in einer Java Swing App ist etwas wie:
%Vor%Ein erfahrenerer Entwickler wird erkennen, dass auf Aktionen über verschiedene Mechanismen zugegriffen werden kann - Menüs, Symbolleistenschaltflächen, möglicherweise sogar andere Arbeitsabläufe im System. Diese Person schreibt eher:
%Vor%Meine Frage ist, Was ist der beste Weg, um diese Action-Objekte so zu verwalten, dass sie in Menüs, Symbolleisten usw. verwendet werden können?
private static final Action
in einer Utility-Klasse? Anwendungen, die ich entwickelt habe und die dieselben Aktionen in Menüs, Symbolleisten und anderen Schaltflächen verwenden müssen, wurden mit dem Swing Application Framework durchgeführt.
Mit diesem Framework können Sie eine Ressourcendatei erstellen, in der Sie den gesamten Menütext, Tooltips und ICONS definieren können. Ich denke, die Symbole sind der Schlüssel, Sie müssen sie nicht selbst laden. Wenn Sie über Aktionen verfügen, die Sie aktivieren / deaktivieren müssen, können Sie außerdem die Methode überschreiben, um ihren Status zu steuern.
Die Website ist es wert, gelesen zu werden.
Action
ist eine schlechte Abstraktion - ein ActionListener
ist mit einem armen Mann Map
verschweißt.
Ordnen Sie sie sicher nicht einem static
zu, da sie veränderbar sind und auch einen Kontext benötigen, um sinnvoll zu funktionieren.
Mein allgemeiner Rat für die GUI-Programmierung ist zu beachten, dass es tatsächlich genauso ist wie jeder andere Programmierbereich. Befolgen Sie die üblichen guten Praktiken. Vor allem, Layering, Trennung von Anliegen, Verwendung (Umsetzung) Vererbung selten und nicht eine große Kugel aus Schlamm zu schreiben.
Siehe auch diese Frage , die ziemlich genau so ist als was du fragst.
Um sie zu organisieren, hängt es davon ab, was Sie mit ihnen machen, und Sie können einige Aktionen auf eine Art und andere auf eine andere Art und Weise organisieren. Es wird alles abhängen.
Was Sie wollen, ist eine konsistente Möglichkeit, eine Aktion in Ihrem Code zu finden / zu erstellen.
Abhängig von Ihrer Benutzeroberfläche müssen Sie möglicherweise zwischen "statischen" Aktionen (dh Dingen, die in Ihrer App immer verfügbar sind, z. B. das Menüsystem) und dynamischen Aktionen, die nur auf bestimmten Bildschirmen oder an bestimmten Orten erstellt werden, unterscheiden / p>
In jedem Fall hilft Ihnen die Verwendung konkreter Unterklassen Ihrer spezialisierten Basisaktion dabei, diese Dinge organisiert zu halten. Was Sie nicht möchten, ist, dass Sie überall in Ihrem Code Dinge wie Labels, Mnemotechniken und Symbole angeben.
Edit: Ich hatte das Gefühl, dass die Leute nicht glaubten, dass das möglich oder einfach war, also habe ich es getan - ungefähr eine Stunde von Anfang an - hätte 40 Minuten gebraucht, wenn ich nur eine einzige Methode benutzt hätte Ziel, anstatt es zu reflektieren, um Methoden für jeden Menüpunkt zu trennen.
Hier ist der Getestete Quellcode . Es funktioniert, aber ist eine große Methode und hässlich - refactor es, wenn Sie es verwenden. Ich werde es vielleicht in den nächsten Tagen ein wenig reparieren, ich wollte immer eine Kopie davon haben, um es wiederzuverwenden.
--- ursprünglicher Beitrag
Denken Sie zunächst daran, Ihren Code von Daten zu trennen. Das bedeutet, dass Sie NIEMALS tippen sollten:
%Vor%Die Zeichenfolge "Datei ..." ist Daten. Wenn Sie auf diese Weise denken, werden Sie feststellen, dass Ihre Frage sich selbst beantwortet.
Zuerst müssen Sie einige Daten aufbauen. Sie müssen "Datei ..." und "Speichern" in Menüs abrufen. Ich beginne normalerweise mit einem String-Array (das Sie leicht in eine Datei verschieben können)
%Vor%Dies ist eines der einfacheren Muster, mit denen ich angefangen habe. Dann können Sie das + -Zeichen auslesen und es verwenden, um "Drop-Down-Ebene im Menü, wenn Sie diese hinzufügen"
Dies ist nur eine dumme Konvention, erfinden Sie Ihre eigenen, wenn Sie es nicht mögen.
Der nächste Schritt ist die Bindung, um den Code zu starten. Du könntest sie alle die gleiche Methode nennen lassen, aber was für ein Schmerz in den Arsch (Giant switch statement). Eine Möglichkeit besteht darin, beim Einlesen der Daten eine Reflektion zu verwenden, um einen Methodennamen zu binden. Hier ist eine Lösung (wieder könnte es nicht Ihrem Geschmack entsprechen)
%Vor%Dann analysierst du das Ding in eckigen Klammern, greifst es reflektiv an eine Methode in deiner aktuellen Klasse an und schon bist du fertig.
Es gibt eine Versuchung, die ich IMMER an diesem Punkt habe, und ich habe gelernt, dagegen anzukämpfen, weil es NIEMALS funktioniert. Die Versuchung besteht darin, den ersten Satz von Daten ("Datei ...") zu verwenden und ihn so zu manipulieren, dass er zu einem bestimmten Muster passt und automatisch an Ihren Code bindet (in diesem Fall entfernen Sie alle Nicht-Alpha-Zeichen, machen Sie den ersten Buchstaben in Kleinbuchstaben und Fügen Sie "Menu" hinzu, um den korrekten Methodennamen zu erhalten. Fühlen Sie sich frei, dies zu versuchen, es ist sehr attraktiv und scheint glatt, aber bereit sein, es zu verlassen, wenn es einige Bedürfnisse nicht erfüllt (wie zwei Menüpunkte mit dem gleichen Namen in verschiedenen Untermenüs).
Eine andere Möglichkeit wäre, wenn Ihre Sprache Schließungen unterstützt, dann könnten Sie den Dateinamen und die Schließung am selben Ort erstellen.
Wie auch immer, sobald Sie mit der Programmierung beginnen, werden Sie feststellen, dass ALLE Ihre Menüstruktur in einer einzigen 10-Zeilen-Methode erstellt wurde und Sie diese an Ihre Bedürfnisse anpassen können. Ich hatte einen Fall, wo ich eine Reihe von Menüs zu einer Tastenhierarchie ändern musste und ich tat es in 2 Minuten.
Am Ende können Sie dieses Muster verwenden, um die Aktionsobjekte einfach einzurichten und ihre Verwendung (an einer einzigen Stelle, in einer einzigen Codezeile) zu ändern, sodass Sie mit ihnen experimentieren. Es gibt viele Möglichkeiten, sie zu verwenden, aber wenn Sie nicht tun, was ich hier empfehle, werden Sie am Ende jeden Menüeintrag für jede Änderung neu implementieren müssen, was wirklich nervig ist - nach einer einzigen Änderung Sie haben mehr Zeit verschwendet, als wenn Sie gerade eine datengesteuerte Lösung implementiert hätten.
Dies ist wirklich nicht hart Code, sollte wie eine Stunde oder zwei dauern, dann müssen Sie nie neue Menü schreiben ("... wieder. Vertrauen Sie mir, diese Art von Werkzeugen ist fast immer es wert.
>bearbeiten:
Ich codiere gerade heutzutage immer datengesteuert. Normalerweise werde ich ein paar Dinge auf die normale Art und Weise prototypieren, das Muster erkennen und umgestalten - und wenn man richtig refaktorisiert, werden die Daten fast immer herausgefiltert und das, was übrigbleibt, ist schön, eng und haltbar.
>Ich könnte tun, was ich oben vorgeschlagen habe, in weniger als einer halben Stunde (vielleicht eine Stunde, um die reflektierende Version zu machen). Dies ist fast immer so lang wie die unstrukturierte Version, und fortan multiplizieren sich Ihre Einsparungen bei jeder Änderung.
Das ist dem, was Leute an Ruby mögen, sehr ähnlich, außer mit Ruby scheinen sie noch mehr Daten in ihren Code einzufügen (was es sehr schwer macht, Ihre Daten vollständig aus dem Code zu extrahieren, was immer ein nettes Ziel für die Internationalisierung ist) ).
Hmm, habe ich erwähnt, dass wenn Sie Ihre Daten so gut extrahieren können, i18n praktisch kostenlos ist?
Ich schlage vor, Sie probieren es einfach mal aus und sehen, was Sie denken. Das Einbetten des Steuerelements in die Zeichenfolgen ist unnötig, wenn es Ihnen unangenehm ist. Ich neige dazu, String- / Objekt-Arrays zu verwenden, nur weil sie sehr einfach einzugeben sind, sich während der Codierung noch in der Datei befinden und später leicht externalisiert werden können. Wenn Sie jedoch YML- oder XML-Dateien oder Eigenschaften mögen, verwenden Sie das, was Ihnen gefällt mit - nur abstrahieren Sie Ihre Daten aus Ihrem Code!
Tags und Links java user-interface swing