Collections PropertyChange bei Maps

G

Gast2

Gast
Hi Leute,

momentan habe ich eine Map in einem meiner Models. Mein Problem ist, dass wenn ich der Map ein Element hinzufüge ein PropertyChangeEvent gefeuert werden soll.

Da der PropertyChangeListener jedoch erkennt, dass es sich um die gleiche Map handelt feuert er nicht.

zuzeit umgehe ich das Problem durch klonen der Map und setzen. Ist natürlich ziemlich unperformant wenn sich nur einige Werte ändern.

Gibts da nen anderen Weg?
 

splinter

Mitglied
Hi

Ich werd aus deiner Problembeschreibung nicht ganz schlau. Wieso hast du ne Map wenn du die gefeuerten Events sowieso ignorierst?
Und wo liegt das Problem dabei genau?
 
N

nillehammer

Gast
Du musst in der Bean, in der Du die Map benutzt, eine eigene put-Methode implementieren, in der du das Event feuerst. Es ist prinzipiell eh keine gute Idee, direkten Zugriff auf Collections/Maps zu erlauben.
 
G

Gast2

Gast
Du musst in der Bean, in der Du die Map benutzt, eine eigene put-Methode implementieren, in der du das Event feuerst. Es ist prinzipiell eh keine gute Idee, direkten Zugriff auf Collections/Maps zu erlauben.

Wollte halt die Binding lib nutzen. Dazu kann ich aber nur die gesamte Map verwenden, da ich mich ja nur auf Bean properties binden kann. Mir ist kein Weg bekannt mich auf ein Element einer Collection zu binden.

In dem speziellen Fall kann ich aber auch eine eigene Listener Implementation machen die dann nur auf konkrete Elemente "hört". Ist vielleicht doch die bessere Idee!

Alternativ: Ich könnte doch eine geklonte Map ins Event packen. Dann hat der Listener keinen direktzugriff auf die Original Collection und der PropertyChangeSupport filterts nicht raus, da die geklonte Map ja nicht identisch ist mit der alten (Es wird nur auf Identität nicht gleichheit geprüft soweit ich mich erinnere).
 

bERt0r

Top Contributor
Nochmal:
Du musst in der Bean, in der Du die Map benutzt, eine eigene put-Methode implementieren, in der du das Event feuerst. Es ist prinzipiell eh keine gute Idee, direkten Zugriff auf Collections/Maps zu erlauben.

Java:
public void putStuffInMap(Object key, Object newValue)
{
     Object oldValue=map.get(key);
     map.put(key,newValue);
     myPropertyChangeSupport.firePropertyChange("StuffInMap",oldValue,newValue);
}

Mir ist kein Weg bekannt mich auf ein Element einer Collection zu binden.
Es ist ja auch der Sinn von Beans dass die Properties nur mit get und set Funktionen manipuliert werden können. Wenn du möchtest dass deine Properties in einer Map gespeichert werden, brauchst du per Bean Definition trotzdem für jeden Eintrag in deiner Map eine get und set Funktion. Wie nillehammer gesagt hat ist das weiterreichen deiner Collection nach außen extrem unschön, nicht zweckmäßig und durch deine clone Spielereien auch unperformant. Persönlich finde ich, dass du dir dadurch die einfachere und bessere Lösung verbaust - Design pattern haben schon ihren Sinn...
 
G

Gast2

Gast
Java:
public void putStuffInMap(Object key, Object newValue)
{
     Object oldValue=map.get(key);
     map.put(key,newValue);
     myPropertyChangeSupport.firePropertyChange("StuffInMap",oldValue,newValue);
}

Soweit klar aber der Listener weiss nicht welcher key dazu gehört. Da meine Listener nur jeweils einen Wert selektiv beobachten ist der propertyChangeSupport wohl doch der falsche Ansatz. Bislang haben halt alle Listener die gesamte Collection bekommen und sich "ihren" Wert herausgenommen.

Ist nicht schön und wird auch nun geändert! (Deswegen ja der Thread ;))

Es ist ja auch der Sinn von Beans dass die Properties nur mit get und set Funktionen manipuliert werden können. Wenn du möchtest dass deine Properties in einer Map gespeichert werden, brauchst du per Bean Definition trotzdem für jeden Eintrag in deiner Map eine get und set Funktion.

Wird so nicht gehen, da ich eine belibige Anzahl Einträge in der Map haben werde.

Wie nillehammer gesagt hat ist das weiterreichen deiner Collection nach außen extrem unschön, nicht zweckmäßig und durch deine clone Spielereien auch unperformant.
Wie gesagt ist mir bewusst und daher der Thread.

Persönlich finde ich, dass du dir dadurch die einfachere und bessere Lösung verbaust - Design pattern haben schon ihren Sinn...

Wenn ich das nicht so sehen würde würde ich nicht nach dem geeigeneten Fragen. Arbeite erst seit kurzem mit Collections (Respektive Java). Daher hab ich gerade in den sehr java typischen Dingen Probleme immer das richtige Pattern für mein Problem zu finden.

Ich denke es ist eventuell sinnvoller das ganze über ein einfaches Obersver/Observable Pattern zu machen und die Map nur als interne Verwaltung der Bean zu nutzen. Die Oberserver sollen ja nur "ihre" Entitiy der Map kennen.

Edit: Es ist keine Bean sondern ein Model. Auch wenn ich die meisten Attribute per Binding nach der Bean Spezifikation ins Programm einbinde!
 

bERt0r

Top Contributor
Jetzt sag mir bitte nicht dass du ein TableModel machst. Es wäre jedenfalls ungemein hilfreich wenn du konkret schreiben würdest was du eigentlich programmieren willst.
 
G

Gast2

Gast
Sorry ich dachte das wär klarer:

Ich habe ein Model mit verschiedenen Daten. Beispielsweise:

- Verbindungsdaten (Schnittstelle, Datenrate, Empfänger, ...)
- Gerätedaten (Typ, Seriennummer, Softwareversion ...)
- GeräteParameter (Intern als Map organisiert)

Die meisten Daten werden per Binding mit den entsprechenden GUI's verbunden. Soweit kein Problem, da es Attribute sind welche per Bean Spezifikation und dem JGoodies Binding Lib angesprochen werden.

Bei den Parametern ist das etwas anders. Diese werden dynamisch vom Gerät heruntergeladen. Es können zudem beliebig viele sein.

Die entsprechenden GUI Komponenten müssten jetzt eigentlich per Binding auf die einzelnen Parameter gebunden werden, was aber nicht geht, da es sich ja um eine beliebige Anzahl handelt die innerhalb einer Map steckt.

Bislang haben sich alle Parameter darstellenden Komponenten auf die gesamte Map gebunden, was eigentlich Quatsch ist da ja nur ein Wert jeweils benötigt wird.

Das soll geändert werden.

Mein Ansatz ist nun bei den Parametern weg vom Binding zu gehen und die Komponenten sich per key (der ist bekannt) auf den entsprechenden Parameter zu registrieren. Das ist dann halt ein klassisches Observer pattern ohne Binding lib.

Ich wüsste halt nicht wie ich mich auf einen Eintrag in einer Map binden kann. Geht vermutlich nicht so ohne weiteres.
 

Michael...

Top Contributor
Ich wüsste halt nicht wie ich mich auf einen Eintrag in einer Map binden kann. Geht vermutlich nicht so ohne weiteres.
Ist m.M. auch nicht sinnvoll. Würde hier Observer bzw. MVC nehmen. Hab's noch nicht ganz überblickt, aber evtl. kann man einzelne Parameter auch zu Objekten zusammen fassen und diese in der Map verwalten.
 
Zuletzt bearbeitet:
G

Gast2

Gast
Ist m.M. auch nicht sinnvoll. Würde hier Observer bzw. MVC nehmen. Hab's noch nicht ganz überblickt, aber evtl. kann man einzelne Parameter auch zu Objekten zusammen fassen und diese in der Map verwalten.

Die Parameter sind Objekte. In denen steckt mehr als nur eine Zahl. Und genau die Objekte stecken in der Map drin (zwecks Verwaltung im Model).

Ich werds über ein Observer Pattern lösen. Macht dann keinen Sinn über Binding.
 

bERt0r

Top Contributor
Je nachdem wie du deine Daten anzeigen willst könntest du auch das ListModel bzw. TableModel Interface implementieren und dir zusätzlich dann eine fireParameterChanged() Funktion schreiben beziehungsweise gleich das Model der Parameter in eine seperate Model-Klasse auslagern, die du dann der Gui-Komponente zurückgibst.
 

Ähnliche Java Themen

Neue Themen


Oben