BeanDev: @ConvertAsProperties zerstört Singleton Pattern von TopComponents
Moin!
Seit dem 10. Januar 2009 gibt es eine nette Erweiterung der NetBeans API für TopComponents. Die @ConvertAsProperties Annotation erlaubt es Eigenschaften des Fensters als Properties zu speichern.
Das ist sehr bequem, weil man sich erstmal nicht generell mit der Serialisierung beschäftigen muss.
@ConvertAsProperties einsetzen
Das Schreiben von Eigenschaften sieht dann so aus:
void writeProperties(java.util.Properties p) {
p.setProperty("version", "1.2");
// TODO store your settings
p.setProperty("dividerLocation", Integer.toString(jSPLMain.getDividerLocation()));
p.setProperty("regionViewer.visible", Boolean.toString(((JPreviewViewer)jPNPreview).isRegionViewerVisible()));
}
Und das Einlesen:
private void readPropertiesImpl(java.util.Properties p) {
String version = p.getProperty("version");
// TODO read your settings according to their version
if ( "1.1".equals(version) ) {
jSPLMain.setDividerLocation(Integer.parseInt(p.getProperty("dividerLocation")));
}
if ( "1.2".equals(version)) {
((JPreviewViewer)jPNPreview).setRegionViewerVisible(Boolean.valueOf(p.getProperty("regionViewer.visible", "true")));
}
}
Die NetBeans Platform kümmert sich automatisch um das Speichern auf die Festplatte (oder sonst wo hin). Ich als Programmierer muss mich darum nicht kümmern. Die TopComponent muss aber annotiert werden:
@ConvertAsProperties(
dtd = "-//org.sepix.tutorialbuilder.ui//Gallery//EN",
autostore = false)
public final class GalleryTopComponent extends TopComponent {
Das erstellt übrigens schon alles das Template, wenn man neue TopComponents mit dem Wizard erzeugt.
Singleton Pattern funktioniert nicht mehr
Nun zum Problem. Es passiert nun, dass zum Einlesen der Properties das Fenster zwei mal erzeugt wird. Einmal zum Einlesen der Eigenschaften und das zweite Mal bei ersten Anzeigen der TopComponent. Das ist natürlich fatal, wenn man davon ausgeht, dass das Fenster ein Singleton sein soll. Zum Beispiel wenn man Resourcen bindet, Listener verknüpft usw...
Es wurde ein Issue dazu angelegt und heute kam
...die Lösung
Es ist tatsächlich kein API Problem, sondern das vom Wizard erzeugte Template hat einen winzigen Bug.
Wie man oben sehen kann, werden die Eigenschaften in der Methode readPropertiesImpl eingelesen. Es gibt auch noch readProperties, die in der alten Version des Templates folgendes machte:
Object readProperties(java.util.Properties p) {
GalleryTopComponent singleton = GalleryTopComponent.getDefault();
singleton.readPropertiesImpl(p);
return singleton;
}
Das sieht zunächst sauber aus, verursacht aber durch den getDefault()-Aufruf eine Instanz, die bedauerlicherweise später verworfen wird.
Das neue (korrigierte) Template wurde nun in den main-golden Trunk integriert und würde folgende Methode erzeugen:
Object readProperties(java.util.Properties p) {
if ( instance == null ) {
instance = this;
}
instance.readPropertiesImpl(p);
return instance;
}
Sieht eigentlich noch logischer aus ;-) - Und das ist übrigens auch die Lösung für aktuelle Versionen (6.7 und 6.7.1) von NetBeans. Einfach in den TopComponents, die man durch den Assistenten erzeugt hatte, die readProperties-Methode mit dem obigen Quelltext austauschen. Dann werden die TopComponents garantiert nur noch einmal erzeugt.
Beste Grüße,
Josch.
Da werden Sie geholfen:
Das deutsche NetBeans Forum
![Validate my RSS feed [Valid RSS]](http://www.sepix.de/fileadmin/valid-rss.png)