# Einstellungen mit Properties speichern



## M_Kay (12. Juni 2010)

Hallo allerseits,

in meinem Programm möchte ich, dass der Benutzer gewisse Einstellungen festlegen und speichern kann. Das kann man ja zB mit java.util.Properties machen.

Nun bin ich am überlegen, wie man das am besten machen sollte.
Die GUI müsste ja wissen, welche key-Namen die einzelnen Klassen für eine gewisse Einstellung benutzen, damit sie den aktuellen Wert anzeigen und bei Veränderung speichern kann.
Das bedeutet ja, dass die GUI so einiges über das eigentliche Programm wissen muss.
Wie bekommt man es hin, dass die Kopplung zwischen den Klassen bzw GUI und Programm möglichst gering bleibt?

EDIT:
Das einzige was mir einfällt, ist eine Klasse zu machen, die Methoden zum Lesen/Schreiben für jede Setting aller Klassen hat. Bei vielen Einstellungen kann die Geschichte aber ziemlich unübersichtlich werden ...

Gruss,
M_Kay


----------



## Anime-Otaku (13. Juni 2010)

Wie wär es eine Klasse zu schreiben, welche alle möglichen Einstellungen als Attribute enthält?
 Dann rufst du eine Methode auf, welche dir diese Datei einliest. Diese muss natürlich die Attribute kennen.


----------



## Thomas Darimont (13. Juni 2010)

Hallo,

was willst du eigentlich Speichern? Nur Strings, Zahlen, booleans, oder beliebige Objekte wie Listen, Sets, Maps, ... etc.?

für deine Anforderungen gibt es zahlreiche Lösungen. Die Frage ist, wie komplex darfs denn werden?
Du könntest beispielsweise  eine Annotation @Setting definieren welche du an die Attribute anträgst die 
Einstellungen enthalten (Strings, Zahlen, boolean, etc.).


```
@Setting
int port = 123;
```

Beim Erzeugen der Instanz welche diese konfigurierbaren Einstellungen enthält könntest du nun generisch per
Reflection die Instanz analysieren und nachschauen ob mit @Setting Attribute definiert sind und diese dann aus 
der vorher eingelesenen Konfiguration befüllen. Das könnte auch über einen entsprechenden Aspekt per AOP bei 
Instanzierung der Konfigurierbaren Klasse geschehen, oder eben von Hand.

Weiterhin könnte man sich überlegen ob die Konfigurationswerte vielleicht von einem Dependency Injection Framework
nachträglich gesetzt werden können. Beispielsweise mit Spring, oder Guice:


```
ApplicationContext context =  ...
context.getAutowireCapableBeanFactory().configureBean(bean, bean.getClass().getSimpleName());
```

oder per Guice

```
...
Injector injector = ...
injector.injectMembers(beanInstance);
```

Das Problem bei diesem Teil des Ansatzes ist das das zurückschreiben der vom Benutzer geänderten Einstellungen 
nicht ganz trivial ist. Für Spring (bei XML Konfiguration) müsste man beispielsweise die BeanDefinition anpassen 
oder neu erzeugen und abspeichern oder die Konfiguration der Properties in eine properties-Datei auslagern welche man dann
mit java.util.Properties.store(...) erweitert etc...

Anstatt ein DI Framework zu verwenden kannst du die Werte natürlich auch selbst per Reflection setzen...

Gruß Tom


----------



## Akeshihiro (13. Juni 2010)

Ich finde den Ansatz genrell etwas komisch, jedenfalls habe ich noch nie einer GUI die Kontrolle über das Programm überlassen. Getreu MVC wird alles in seine einzelenen Bestandteile zerlegt und via Events kommuniziert. Die GUI ist dann ein View und dient lediglich als Ersatz für IO, in der der Benutzer bequem arbeiten kann. Da alles mögliche als View dienen kann, nicht nur ne GUI, müssen entsprechende Schnittstellen klar definiert werden, damit man Werte holen und setzen kann. Für die Datenhaltung dienen dann Models. Die Verarbeitung übernehmen Controller. Je nachdem wie komplex das Programm werden soll, gibt es eben mehrere Controller, die sich die verschiedenen Aufgaben teilen.

Bevor ich noch abschweife ... Die GUI darf eigentlich nicht über die Verarbeitungslogik verfügen, denn sobald sich die GUI ändert, muss die Logik angepasst werden oder wenn keine GUI gebraucht wird, kann man auch das eigentliche Programm nicht mehr nutzen, da es von der GUI abhängig ist. Das würde ich an deiner Stelle nicht versuchen so zu lösen. Guck dir einfach mal ein paar Beispiele für MVC an und dann kommst du schnell auf eine eigene Idee für eine Implementierung.


----------



## M_Kay (13. Juni 2010)

Akeshihiro hat gesagt.:


> Ich finde den Ansatz genrell etwas komisch, jedenfalls habe ich noch nie einer GUI die Kontrolle über das Programm überlassen.


Das habe ich doch auch nicht vor 
Generell soll keine Logik in die GUI, deswegen möchte ich ja auch eine Settings-Klasse, mit der die GUI und das Programm kommuniziert.
Wenn ich innerhalb der Settings-Klasse für jede Einstellung eine Getter/Setter-Methode mache, dann wird das ganze aber ziemlich aufgebläht. Deswegen bin ich am überlegen, ob ich in die Settings-Klasse eine Map packe, welche die Einstellungen hält und von außen über eine Getter- und Setter-Methode Einstellungen gelesen und geschrieben werden können.
Die GUI müsste dann "nur" noch wissen, welche keys die Programm-Klassen verwenden, um die aktuellen Einstellungen anzeigen zu können. Aber irgendwas muss die GUI ja sowieso wissen, sonst kann sie ja nichts darstellen, oder? 

Da ich das Programm bisher nach MVC aufgebaut habe, möchte ich auch hier nicht davon abweichen und frage ja deshalb nach, wie man das am besten und einfachsten löst 

Das ganze soll natürlich so einfach wie möglich gehalten werden, weil das Projekt selbst auch nicht so riesig ist. Extra noch ein Framework zu verwenden, hatte ich nicht vor 

Um nochmal auf die Frage von Tom zurückzukommen:
Die Programmeinstellungen bestehen bisher aus simplen Strings und Zahlen etc..
Der Programm-Status soll später aber auch gespeichert werden können: zB Objekte, die gerade in einer Liste dargestellt werden und den aktuellen Zustand des Programms repräsentieren. In dem Fall wird es nötig sein, auch das Objekt zu speichern, was ich ja dann ebenfalls in meine Settings-Klasse auslagern könnte.


----------



## Akeshihiro (13. Juni 2010)

Ja gut, dann tut es mir leid, ich hatte verstanden, dass du alles aus der GUI heraus "verwaltest".


> Das bedeutet ja, dass die GUI so einiges über das eigentliche Programm wissen muss.


Deshalb ^^ Aber wie ich schon sagte, ist die GUI nur eine andere Form von IO, mehr nicht. Sie darf nichtmal wissen, dass es ein Programm unten drunter gibt geschweige denn darauf zugreifen. Wenn daten zwischen GUI und Logik ausgetauscht werden müssen, dann über ein Model.


----------

