Das Notes Forum

Lotus Notes / Domino Sonstiges => Java und .NET mit Notes/Domino => Thema gestartet von: MadMetzger am 09.03.06 - 21:40:12

Titel: Componenten auf einer JDesktopPane überprüfen
Beitrag von: MadMetzger am 09.03.06 - 21:40:12
Hallo zusammen!

In meinem Studium bin ich gerade mit einem Projekt beschäftigt. Wir sollen eine Anwendung zur Simulation von Stellen-Transitions-Netzen(PetriNetze) auf Basis von Java erstellen.

Hierbei bin ich auf eine Frage gestossen: Ich kann ein Netz mehrfach simulieren und solange die Anwendung offen ist, bleiben die Simulationen erhalten(Persistenz war nicht Bestandteil der Aufgabe). Bestehende Simulationen eines Netzes werden mir in meinem Hauptfenster innerhalb einer JList angezeigt. Nach gewisser Anzahl von Simulationsfenstern, kann es sein, dass man den Überblick verliert. In dem Fall möchte ich über einen Doppelklick auf den Eintrag in der Liste mir das Fenster wieder holen. Dazu muss ich für jedes Fenster(ein JInternalFrame), dass in der JDesktopPane abgelegt wurde, überprüfen, ob es eine Referenz auf diese markierte Simulation hat. Dazu lasse ich mir von der Pane alle Components (mit pane.components() )zurückgeben, jedoch ist mir bei dem Array, dass da zurückkommt nicht ganz klar, wie ich darüber iterieren kann. Wenn ich mit

Anbei ein Schirmschuss zur Verdeutlichung...
Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: Ralf_M_Petter am 10.03.06 - 08:40:39
Mir kommt der Ansatz zwar etwas kompliziert vor, du könntest für die Liste auch ein eigenes Datenmodell verwenden, wo dann die Referenz auf den Internalframe abgelegt ist. Aber poste doch mal die Stelle im Source wo der Fehler passiert mit der Angabe eventuell des StackFrames. Dann werden wir sicher eine Lösung finden.

Grüße

Ralf
Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: MadMetzger am 10.03.06 - 09:37:30
Du meinst im Prinzip eine Wrapperklasse um die Simulation herum, die eine Referenz auf das Fenster hat? Das klingt sogar sehr gut... werde ich heute Mittag mal ausprobieren...
Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: MadMetzger am 10.03.06 - 21:29:08
Tja, klappt ja an sich ganz gut mit der Wrapperklasse, ich kriege dann auch das passende Fenster i Zugriff, nur weiß ich nie genau, was ich mit dem Fenster machen soll. Es kann geschlossen worden sein, oder minimiert, oder auch nur hinter anderen versteckt. Welche Methode muss ich von den JInternalFrames aufrufen, damit ich das Fenster in jedem Fall kriege? Im Moment sage ich einfach nur setVisible(true) und es geht zwar aber irgendwie klappt es manchmal(?) nur auf den zweiten Klick und wenn es minimiert war, kommt zwar das Fenster in den Vordergrund aber der minimierte "Rest" bleibt bestehen...  ???
Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: flaite am 11.03.06 - 22:26:09
Ralfs Ansatz würde ich erstmal zustimmen. Das mit dem ListModel.
Warum Wrapperklasse? Implementierst du http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/ListModel.html ?
JInternalFrame für User schliessbar machen und in der Liste lassen hört sich auch irgendwie gefährlich an.
JInternalFrame hat btw. sich vielversprechend anhöhrende Methoden wie toFront() und show().
Den Status kannst du offenbar mit so Methoden wie isIconified (in JInternalFrame) abfragen. Hab allerdings noch nie JInternalFrame benutzt. Aus meiner Erfahrung mit Swing würd ich sagen, dass du irgendwann weisst wie.
Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: MadMetzger am 12.03.06 - 00:07:00
Für den Moment habe ich das minimieren verboten. Ich habe es nicht hinbekommen bzw. habe aus Zeitgründen erstmal diesen Weg gewählt... Dann kann ich das Fenster schließen und bekomme die Simulation wieder über die Liste per Doppelklick geöffnet.

Ich habe irgendwie nicht die Unterschiede zwischen show() und setVisible(true)  und anderen Methoden verstanden... die waren nicht so klar beschrieben in der API-Doku... Daher dieser Weg.

Du hast insofern recht, dass man Swing am ehesten beim Benutzen lernt. Vor diesem Projekt wusste ich gerade mal, wozu man Swing gebrauchen kann...

Trotzdem erstmal ein Dankeschön an alle! Werde mich jetzt anderen Problemen dieser Anwendung zuwenden, bzw. fürs erste schlafen gehen und PetriNetze PetriNetze sein lassen...

Gute Nacht!
Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: Ralf_M_Petter am 12.03.06 - 16:41:36
Mad metzger du verwendest aber keine Methoden von ausserhalb des Event Handler Threads. Gerade wenn in Swing Probleme auftreten, die machmal da sind und dann funktioniert wieder alles einwandfrei, sprechen dafür, dass da nicht sauber gearbeitet wird. Wie gesagt, bei Swing vor allem in den neueren Versionen darf nur von Event Handler Thread aus auf Swing Objekte zugegriffen werden. Wenn du das Bedürfnis hast, von anderen Threads auf Swing zuzugreifen musst du immer invokeLater verwenden.

Grüße

Ralf
Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: flaite am 12.03.06 - 18:42:18
Ziemlich allgemeines Gewäsch, aber sehr wahr:
Sobald du mit etwas komplexen und für dich unbekannten wie Swing unter Zeitdruck arbeitest, wirst du alle Prinzipien über sauberes Design über Bord werfen und in einer Soße mit größer werdenden Klumpen enden (engl: un-maintainable code). 
Die Frage geht ja nicht über Petri-Netze, sondern über - sagen wir - "Fenster-Management", d.h. wo hälst du die Referenzen der JInternalFrames und wie bringst du sie in den gewünschten state.

Ich würd sowas in einer Klasse PresentationModel halten, die völlig unabhängig von JFrame oder sonstigen komplexen Swing-Klassen ist.
Du kannst anfangen, dir anzuschauen wie andere openSource Projekte Fenster-Management steuern. Oder Bücher kopieren. Wobei sich die meisten Swing Bücher sich mit den zahlreichen Swing-Klassen beschäftigen und weniger mit dem allgemeinen Design einer Desktop Anwendung auseinandersetzen. Eine Ausnahme ist das hier: http://www.sourcebeat.com/TitleAction.do?id=10

zu invokeLater:
Ich habs gerade wieder selber in meinem Webservices-Projekt für HELP gemerkt: Threading Issues können komplex werden. Es gibt Alternativen. Das ist ziemlich gut für das allgemeine Verständnis: http://www.javalobby.org/members-only/eps/galbraith-swing-2/?source=archives

Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: MadMetzger am 12.03.06 - 20:23:32
Aufgrund von Zeitdruck ist mir das im Moment nicht möglich solche Dinge noch zu implementieren... Leider hat ein Tag nur 24 Stunden und ein paar Klausuren muss ich ab morgen auch noch schreiben.

Der Hinweis auf eine Klasse PresentationModel klingt recht gut, bei mehr Zeit würde ich mich damit auch noch einmal auseinandersetzen...

hier mal ein Codebeispiel, in dem ich die Fenster aufrufe:

Code
private void getAendernButtonAction(){
        NetChangingWindow netChangingWindow = (NetChangingWindow) this.uebersichtList.getSelectedValue();
        if (netChangingWindow!=null){
            Aenderungsfenster af = this.controller.editNet(netChangingWindow);
            if(!this.desktopPaneHasWindow(af))this.hauptfensterDesktopPane.add(af);
            af.setVisible(true);
            af.toFront();
        }else{
            Runnable r = new StatusZeilenHandler(Constants.MESSAGE_NO_NET_FOR_DESIGNING_SELECTED, this.getStatusZeilenTextField());
            new Thread(r).start();
        }
        
    }

NetChangingWindow ist meine Wrapperklasse, die mir eine Referenz auf mein Netz und das Änderungsfenster bietet.

Wie würde ich denn bei einem minimiertem Fenster vorgehen? isIconified abfragen und dann?
Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: flaite am 12.03.06 - 22:03:01
Aufgrund von Zeitdruck ist mir das im Moment nicht möglich solche Dinge noch zu implementieren...
Gerade in der Uni ist es oft schlau, Dinge lieber ein bischen schneller zu machen, auch wenn die Qualität drunter leidet.
Hört sich komisch an, ist aber leider so.
Hab mal einen Fanatiker als Freund, der am Ende für 1-Monats Hausarbeiten 10 Monate brauchte. Die waren dann auch wirklich gut. Der Preis an Zeit war aber trotzdem nicht vertretbar.
Ich kapiere diesen Teil überhaupt nicht:
Code
 Runnable r = new StatusZeilenHandler(Constants.MESSAGE_NO_NET_FOR_DESIGNING_SELECTED, this.getStatusZeilenTextField());
            new Thread(r).start();
Sieht für mich nach überkomplexer Patternities aus?

Ich habs nicht ausprobiert, aber so die Art
Code
else {
   SwingUtilities.invokeLater(new Runnable() {
public void run() {    getStatusZeilenTextField()).setText(Constants.MESSAGE_NO_NET_FOR_DESIGNING_SELECTED);
}
}); 
} // end if
Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: Ralf_M_Petter am 13.03.06 - 07:47:14
Hallo MadMetzger!

Ist mir zwar jetzt etwas unklar, warum du einen neuen Thread machst. Aber genau in diesem neuen Thread darfst du nicht auf Swing Klassen zugreifen, da du ja dann nicht mehr im Event Handler Thread bist.

Grüße

Ralf
Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: flaite am 13.03.06 - 08:23:48
Aus dem Kopf:
1. Du packst Operationen in einen neuen Thread, wenn die Operation relativ viel Ressourcen (= Zeit) benötigt (z.B. ein RDBMS call). Sonst friert nämlich die Gui ein. In dem code-snippet, das wir hier diskutieren, brauchst du das gar nicht.
2. Wenn du einen neuen Thread benutzen solltest (wg. 1), dann sollte man das nur über SwingUtilities.invokeLater() machen.
3. Um das ganze Thread-Management Zeugs einfacher zu machen, gibt es von Sun die Klasse SwingWorker (suche auf Java.net). Ausserdem noch ein paar openSource Projekte, die aber weitgehend in dem JavaLobby Link erklärt werden. 
Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: MadMetzger am 13.03.06 - 08:38:41
Also den neuen Thread mache ich nur auf, um in einer Statuszeile untem im Fenster die von der gefangenen Exception mitgelieferte Message auszugeben und weiter arbeiten zu können. Also wenn ich Threadmäßig was an der GUI machen will, sollte ich mit SwingUtilities.InvokeLater arbeiten?
Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: flaite am 13.03.06 - 08:43:16
Die Aktion benötigt nicht viele Ressourcen.
Du brauchst das überhaupt nicht in einen neuen Thread tun.
Neuer Thread nur, wenn der code wirklich viele Ressourcen benötigt (Kandidaten: Calls gegen Lotus Notes/RDBMS/Filesystem/ Webservices)
Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: Ralf_M_Petter am 13.03.06 - 08:45:11
Ja wie schon mehrmals gesagt, du darfst von anderen Threads als der Event Handler Thread Swing Objekte nicht verändern. Falls du in einem anderen Thread bist, musst du über invokeLater die Änderungen an den Swing Objekten machen. Normalerweise schaut die Aktion so aus.

Benutzer klickt einen Button.
Der Event Handler Code des Buttons muß eine länger dauernde Operation durchführen, deshalb startet er einen neuen Thread der z.B. Daten aus einer SQL Datenbank ausliest. In der Zwischenzeit werden neue Ereignisse in der Gui ausgeführt. Das heisst, dass Fenster reagiert auf den Benutzer. Wenn der neue Thread fertig ist, muß er mit invokeLater wieder Code starten, der die Ergebnisse z.B. an das Tablemodell einer JTable übergibt.

Grüße

Ralf
Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: MadMetzger am 13.03.06 - 09:02:12
^^Sie verbraucht nicht viele Ressoucen, aber die Meldung soll angezeigt werden und nach einer festzulegenden Zeit wieder verschwinden. Und wenn ich das direkt in diesem Thread gemacht hätte, dann wäre nach meinem Verständnis die GUI blockiert. Kann mich aber auch täuschen...
Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: Ralf_M_Petter am 13.03.06 - 09:05:45
Du täuscht dich nicht, das ist völlig richtig. Du musst in dem Thread der eine Zeiteinheit wartet  2 mal invokeLater verwenden einmal um die Meldung auszugeben und einmal nach Ablauf der Wartefrist um die Meldung zu löschen. Aber Vorsicht. Während die Meldung angezeigt wird, kann schon wieder eine neue Meldung kommen. Hier solltest du dann Vorsorge treffen, dass du diese neue Meldung nicht zu früh löscht. Ausserdem würde ich hier mit einem vorgeladenen Thread arbeiten und nicht jedesmal einen neuen gernerieren, da Threadgeneration je nach Betriebssystem auch eine aufwendige Operation ist.

Grüße

Ralf
Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: flaite am 13.03.06 - 09:34:42
Wenn dieses "Fehlermeldung geht automatisch nach einer gewissen Zeit weg"-Feature nicht explizit in der Aufgabenstellung stand, würde ich es sofort rausnehmen. Mit sowas handelst du dir sonst noch Minuspunkte ein.
Thread Management ist k.o.m.p.l.e.x.
Hier wird das ein bischen angesprochen:
http://weblogs.java.net/blog/javaben/archive/2005/04/index.html
SwingWorker, Foxtrott und ähnliche Ansätze helfen, die Sachen einfacher zu machen (glaub ich).
Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: Ralf_M_Petter am 13.03.06 - 09:39:12
Kann Axel nicht zustimmen. Auf der Uni will man ja was lernen und gerade diese Aufgabenstellung ist ein Superbeispiel um komplexeres Threadmanagement zu lernen. Heute sollte jeder Java Entwickler Threads perfekt beherrschen, da das aufgrund der Prozessorentwicklung extrem wichtig wird. In Zukunft werden die grossen Performanceschübe wahrscheinlich nur noch von Multi Cores kommen und die kann man halt nur ausnutzen wenn man auch Multithreading behrerrscht.

Grüße

Ralf
Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: flaite am 13.03.06 - 10:23:01
und gerade diese Aufgabenstellung ist ein Superbeispiel um komplexeres Threadmanagement zu lernen.
Ralf,

wir kennen die Aufgabenstellung nicht. Ich weiss nur, dass Dozenten extrem negativ reagieren, wenn man etwas schlecht einbaut das gar nicht gefragt war.
Wenn das "Nachricht verschwindet automatisch"-Feature nicht gefragt war: Ein modaler Dialog und ein "Ok, schliessen" Button tut es auch.
Nix gegen Lernen. Aber bei Dingen, die von anderen bewertet werden, sollte man sich 2x Fragen, was überhaupt gefordert war.

Zitat
Heute sollte jeder Java Entwickler Threads perfekt beherrschen, da das aufgrund der Prozessorentwicklung extrem wichtig wird. In Zukunft werden die grossen Performanceschübe wahrscheinlich nur noch von Multi Cores kommen und die kann man halt nur ausnutzen wenn man auch Multithreading behrerrscht.
Wie viele Java Programmierer beherrschen Threads wirklich? Laut Bruce Eckel waren vor Java 5.0 viele Java Thread Dinge buggy (z.B. volatile keyword). Als J2EE-Entwickler hat man sowieso nur sehr eingeschränkt mit Threads zu tun. Die Requests kommen treffen zwar multithreaded auf die Komponenten, jedoch muss man praktisch nie selbst neue Threads starten.

Ich glaub die größten von Programmierer verursachten Unfälle entstehen dadurch, dass Leute ihr eigenes vereinfachtes innere Bild einer komplexen Sache (Threads) mit der Wahrheit verwechseln.
Ich beschäftige mich btw. selbst mit Threads, halte es aber für komplex. Und ich denke es geht einer Menge Java-Programmierern so. Bruce Eckel findet es auffällig, dass die in Java 5.0 völlig neuen Threading Geschichten kaum diskutiert werden. Eine mögliche Erklärung ist, dass viele Java-Programmierer lieber darauf verzichten Thread-Gurus zu werden. 
In der Aufgabenstellung von Markus gehts nicht primär um Threading. Und wenn er nicht so die Erfahrung damit hat, fehlt vielleicht der Fokus, um es richtig zu machen. Dann ist es besser, Threading auf eine längerfristige "needs-work"-Liste zu packen und jetzt erstmal - wenn möglich - Abstand halten. 
Threads ist auf jeden Fall ein interessantes Thema, über das man auch eine Menge andere Dinge verstehen kann.

Gruß Axel
Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: MadMetzger am 13.03.06 - 13:39:37
Also eigentlich hatte ich (bis dato)gar kein Problem mit dem neuen Thread, der mir in das Textfeld was reinschreibt, sollte aber ich werde mal auf invokeLater() umprogrammieren, damit das sauberer ist. Mein Problem war in dem wahr-Teil der if-Abfrage, dort arbeite ich nämlich mit den Fenstern, die ich  wieder herstellen etc. will. Aber für den Moment lasse ich das bei den Fenstern erst mal genauso, da ich ja auf das gleiche auch über meine Liste zugreifen kann.

Zu dem geforderten, das mit der Statuszeile stand nicht in der Aufgabe, aber wurde von unserem Dozenten in mehreren Gesrpächen erwähnt, da ihn modale Dialoge nerven würden...
Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: flaite am 13.03.06 - 14:26:15
Also eigentlich hatte ich (bis dato)gar kein Problem mit dem neuen Thread, der mir in das Textfeld was reinschreibt,
Ralf hat aber Recht: Das ist ein no-never. Auch wenn es jetzt funktioniert. Hör dir ruhig mal das Zeug hinter dem geposteten Javalobby Link an. Das ist wirklich gut.
Ich hör mir das auch noch mal an. Danach kann ich sicher sagen, warum genau das ein no-never ist.  ;D Ich wußte das mal.

Zitat
Zu dem geforderten, das mit der Statuszeile stand nicht in der Aufgabe, aber wurde von unserem Dozenten in mehreren Gesrpächen erwähnt, da ihn modale Dialoge nerven würden...
Ok. Du kannst aber genauso Dinge in die Statuszeile schreiben und die nicht automatisch dort weglöschen. Du mußt nur hinter jeder Useraktion (Buttons und so) die Statuszeile leeren (gemeinsame Superklasse).
Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: flaite am 13.03.06 - 18:29:04
Markus,

du kannst Glück gehabt haben, weil:
JTextComponent.setText() ist eine Ausnahme zum Swing Komponenten nur im AWT Event Thread Gesetz ansprechen!.
Der AWT Event Thread ist der Thread, den du nicht selber gestartet hast.
Es gibt ein paar wenige Ausnahme. Ansonsten ist das nicht Thread-Safe und die merkwürdigsten Dinge können passieren.

Nochmal: Lass dich ruhig mal hiervon vollquatschen:
http://www.javalobby.org/members-only/eps/galbraith-swing-2/index.html?source=archives
Die Registrierung ist umsonst.

Gruß Axel



Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: MadMetzger am 14.03.06 - 16:53:39
Vielen Dank erstmal für die Tipps, die ich von euch bekommen habe. Auch wenn ich nicht alle davon mehr bis heute umsetzen konnte, da heute die Anwendung abzugeben war. Hat uns noch die ganze letzte Nacht gekostet, dafür aber funktioniert (fast) alles. Die Anwendung merkt nur eine Kleinigkeit nicht und reagiert nicht bei übermäßig großer Anzahl von möglichen Aktivierungen für ein Netz. Die Note ist auch dementsprechen gut ausgefallen, also können alle hier Beteiligten sich sagen, sie haben einen Teil dazubeigetragen.

Wenn jemand mal die Anwendung sehen möchte, kann er mir ja eine PM schreiben, dann kann ich die gerne mal zur Verfügung stellen.
Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: MadMetzger am 15.03.06 - 14:36:49
Ich muss noch mal was fragen... ich habe mir jetzt das Projekt aus Eclipse als JAR-File exportiert, jedoch kommt beim Starten die Meldung, dass die main-Class nicht gefunden wurde. Ich habe aber die richtige Klasse für die Main-Class beim Export ausgewählt... Seltsam...  :-:
Titel: Re: Componenten auf einer JDesktopPane überprüfen
Beitrag von: MadMetzger am 17.03.06 - 11:10:47
So, habe meine Fehler gefunden... musste einfach nur die Packages zum Export markieren und nicht das ganze Projekt, da ich externe JARs, welche ich noch im Class-Path eintragen musste, eingebunden habe. Danach lief es dann...