SingleFrameApplication - Preferences

hesk

Erfahrenes Mitglied
Hallo!

Ich habe eine SingleFrameApplication mit vielen Klassen.
Weiters hab ich einen PreferenceManager der alle Einstellungen lädt/speichert.

Gibt es eine Möglichkeit diesen Manager in der ganzen Application zur Verfügung zu haben ohne ihn in jede Klasse zu übergeben?

So stell ich es mir vor:
Application startet
PreferenceManager wird erstellt, Einstellungen werden geladen
Application.put( PreferenceManager )
In einer ganz anderen Klasse:
PreferenceManager pm = Application.get( PreferenceManager);

So kann es natürlich nicht funktionieren, ich wollt nur meine Idee verdeutlichen:)

Vielen Dank
 
Hi,

die einzige Möglichkeit dein Problem ohne großen Aufwand zu lösen, fällt mir nur die Möglichkeit ein, die Klasse PreferenceManager static zu machen. Dadurch kannst du auf alle Methoden von außerhalb zugreifen.
Das laden der Einstellungen würde ich dann auch über eine static Methode realisieren, die du beim Programmstart ein mal aufrufen müsstest.

Der Nachteil von dieser Lösung: Der PreferenceManager bleibt solange erhalten (bzw. im Speicher) bis das Programm beendet wird. Wobei dich das wahrscheinlich nicht weiter stören dürfte, wenn du beim Programmende alle Einstellungen über den PreferenceManager speichern willst.

Viele Grüße

Sporticus
 
Wenn der PreferenceManager an sich static ist, dann müssen auch seine Fields static sein.
Das macht dann wenig Sinn, da ich während des Programms ja Fields ändern muss(welche dann am Ende gespeichert werden)
 
Warum setzt du die Variable nicht in dem jeweiligen Objekt, in dem sie benötigt werden und lädtst dann über den Konstruktor den Variableninhalt.

Beispie:

Code:
private int field;

public Test() {
   this.field = PreferenceManager.get("test.field");
}

Das wäre meiner Meinung nach einfacher. Und außerdem bezieht sich die Variable doch schließlich immer auf ein bestimmtes Objekt, also warum sollte dann der PreferenceManager alle Variablen verwalten?
 
1)

Im PreferenceManager sollen bestimmte Einstellungen gespeichert werden(kommen in die regestry)
D.h. ich hätte gern dort alle Einstellungen.

2)
Ich hab gerade probiert die Klasse static zu machen. Geht nicht. Nur public, abstract oder final ist erlaubt.
Weiters, wenn man es so macht wie oben gezeigt, wie würde man die Variable dann setzen?
Damit beim speichern der PreferenceManager weiß was er speichern soll.

Mir wäre die Lösung noch immer am liebsten, wo ich das PreferenceManager-Object in eine Art Container gebe, und überall in der Applikation drauf zugreifen kann. So wie die resourceMap.
 
Also wenn man mal ein wenig OOP denkt, dann kommen die Variablen in das Objekt, zu dem sie gehören.

Ich habe dir mal ein kleines Code-Beispiel geschrieben:

PreferenceManager
Code:
import java.util.prefs.Preferences;

public class PreferenceManager
{
	private static PreferenceManager prefManager;
	
	private Preferences pref;

	/**
	 * 
	 */
	public PreferenceManager() {
		pref = Preferences.userNodeForPackage(this.getClass());
		prefManager = this;
	}
	
	/**
	 * @param key
	 * @param value
	 */
	public void put(String key, String value) {
		pref.put(key, value);
	}
	
	/**
	 * @param key
	 * @param def
	 * @return
	 */
	public String get(String key, String def) {
		return pref.get(key, def);
	}
	
	/**
	 * @return
	 */
	public static PreferenceManager getInstance() {
		if(prefManager != null) {
			return prefManager;
		} else {
            prefManager = new PreferenceManager();
            return prefManager;
        }
	}
}

TestObject
Code:
public class TestObject
{
	private final PreferenceManager prefs;
	
	private String a;
	
	/**
	 * 
	 */
	public TestObject() {
		this.prefs = PreferenceManager.getInstance();
	}
	
	/**
	 * 
	 */
	public void init() {
		a = prefs.get("testobject.a", "");
	}
	
	/**
	 * 
	 */
	public void destroy() {
		prefs.put("testobject.a", a);
	}
}

Ich hoffe das veranschaulicht mein Gedankengang/Beispiel ein wenig. :)
 
Zuletzt bearbeitet:
Wow..vielen Dank. Wie man mit der Zeit immer mehr Sachen lernt:)

Hab deine Variante eingebaut, und sie funktioniert.
Ist eine gute Variante um nicht alle möglichen Objecte im Konstruktor übergeben zu müssen.

Wegen den Fields:
Du meintest dass die Fields eher bei den jeweiligen Objecten stehen sollten. Weil es dann OOP wäre.
Aber wenn man den PreferenceManager als zentrale Einstellungsspeicher-Klasse betrachtet, dann sollten doch eher dort alle stehen. Weil dann hat man alle auf einen Blick und weiß was gespeichert wird.
Und jede Klasse kann sich von dort die nötigen Sachen holen.

Ein Bespiel was in meinem Programm vorkommt:

Wenn man sich auf einen Server connected, dann wird ein gewisser Hinweis ausgegeben. Der ist je nach Server unterschiedlich. Jetzt gibt es die Klasse InformationDialog welche den Hinweis anzeigt.
Dort gibt es die Option "nicht mehr anzeigen". Wenn dies angehackerlt ist, dann wird im PreferenceManager(also in er regestry) ein Key hinterlegt, welcher sagt dass bei diesem Server der Hinweis nicht mehr angezeigt werden soll.

Im PreferenceManager sieht das Field so aus:

Code:
private Map<String, Integer> notShowAgain;

Die set-Methode:
Code:
public void setNotShowAgain( String node, String subNode, Integer flag )
{
     this.notShowAgain.put( "notShowAgain." + node + "." + subNode, flag );
}

Der Key welcher in der Regestry abgespeichert wird ist zb folgender: notShowAgain.Servername.info= 1

Beim nächsten connecten auf dem Server wird nachgeschaut ob ein "info"-key für diesen Server vorhanden ist, und ob er auf 1 ist. Falls ja, wird der InformationDialog nicht angezeigt.

Sollte die notShowAgain-Map nun wirklich wo anders liegen? Wäre das eher OOP?
 
Ok, bei dem Punkt kann man sich wahrscheinlich drum streiten, ob und wie das nun am ehesten OOP ist.

Wenn ich noch etwas anmerken darf, würde ich den Value für 'notShowAgain.Servername.info' nicht mit 1/0 besetzen sondern eher mit true/false. Du wirst von deinem Dialog doch wahrscheinlich (wenn es eine Checkbox ist) einen true/false-Wert zurück bekommen. Dann kannst du diesen doch auch so wie er ist abspeichern.

Ich würde es eher so realisieren, dass ich vorm öffnen des Dialoges über den PreferenceManager den Value für den Key für diesen Server mir geben lasse. Dann überprüfe ich, ob dieser true/false ist und öffne dann den Dialog dementsprechend.

Code
Code:
public class Server
{
	private PreferenceManager pref;

	/**
	 * 
	 */
	public Server() {
		pref = PreferenceManager.getInstance();
	}
	
	/**
	 * @param server
	 */
	public void connect(String server, int port) {
		String message = connectToServer(server, port);
		
		boolean notShowAgain = pref.get("notShowAgain."+getName()+".info", false);
		
		if(!notShowAgain) {
			boolean notShowAgainDialog = Dialog.open();
			pref.put("notShowAgain."+getName()+".info", notShowAgainDialog);
		}
	}
	
	/**
	 * @param server
	 * @param port
	 * @return
	 */
	private String connectToServer(String server, int port) {
		// Stelle die Verbindung zum Server her
		// ...
		return message;
	}
}
 
Zuletzt bearbeitet:
Ja, wenn es sich nur um diesen Dialog handeln würde, dann wäre ein Boolean besser.

Aber der PreferenceManager soll für mehrere Dialoge speichern, ob diese nochmal angezeigt/nachgefragt werden soll. Manche enthalten auch eine Ja/Nein Abfrage.

Drum:
Code:
@DoNotUseForDebug
public static final int DO_NOT_REMEMBER = 0;
@DoNotUseForDebug
public static final int REMEMBER_YES = 1;
@DoNotUseForDebug
public static final int REMEMBER_NO = 2;
@DoNotUseForDebug
public static final int REMEMBER_IT = 3;
 
Zurück