Laden von Dateien

jH

Mitglied
Hallo,

Ich hätte mal eine allgemeine Frage zum Laden von Dateien. Wie ich Dateien lade und speichere ist kein Problem, das habe ich auch schon erfolgreich implementiert.
Nur hab ich noch ( glaube ich ) einen kleinen Denkfehler wenn es darum geht die Informationen aus der geladenen Datei bei Programmlaufzeit zu halten.

Ich hab in meinem Projekt eine MVC Struktur. Nun steh ich vor der Frage, wo ich meine geladene Datei bei laufzeit halte, sprich wie ich die Infos aus der Datei für das Programm und die GUI uir Verfügung stelle. Bis jetzt habe ich es so gemacht das ich die Datei in einer Instanz ihrer Klasse im Controller halte. Jedoch erscheint mir das nicht vernünftigt, bzw hab ich damit einige Probleme wenn es um die GUI Aktualisierung geht (dazu aber eventuell später mehr).

Wie geh ich da am besten vor. Gibt es da irgendwelche Infos die ich mir durchlesen kann oder hat jemand da ein paar Denkanstöße oder Ideen? Bin für jeden Tipp dankbar 🙂

Grüße
jh
 
evtl. weiß jemand anderes was du meinst/willst..ich würde erwarten, dass Daten die du beim Programmstart lädst, oder nach Programmende speicherst, das Model persistieren => imho müssen die Daten in das Model, oder was für Daten sind das denn...?
 
Danke für deine Antwort. Ist etwas knifflig das richtig zu schreiben was ich meine 😉
Also meine Frage ist, wie bzw. wo ich meine geladene Datei in meinem Programm halte. Also die Datei ist eine von mir selbst entwickelte Klasse die ich per Serializable gespeichert habe. Die Informationen aus der Datei bekomme ich auch alle wunderbar (wie gesagt, laden und speichern klappt). Ich habe es bis jetzt immer so gemacht, das ich meiner "controller" klasse (vom MVC Konzept) eine Instanz der Klasse angelegt habe, mit der mein Programm arbeitet. Wenn ich nun eine Datei geladen habe, wurde die Instanz (mit einem Setter), jedes mal dann neu gesetzt. Nun frag ich mich ob das auch "best practive" ist oder ob es dazu irgendwo informationen gibt.
 
bestPractice ist -zumindest hier im Forum^^- uns zu sagen, welche Art von Daten in dieser Datei gespeichert werden. Grundsätzlich hört sich das aber für mich recht vernünftig an...
 
Dann dochmal ne runde Code 😉

Java:
/**
 * 
 */
package mvc.model;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.nio.channels.FileChannel;
import java.util.Observable;
import java.util.Vector;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileFilter;
import mvc.controll.Controller;

/**
 * @author henrichj
 * 
 */
public class SystemCD implements Serializable {
	private static final long serialVersionUID = 4257325752674191118L;
	private static Controller controller;
	private String s_name;
	private File s_file;
	private Vector<SysDataFile> s_documents;

	// Arrays für die Sprachen
	private static final String[][] langArray = new String[6][6];

	private static final String[] GERMAN = new String[6];
	private static final String[] ENGLISCH = new String[6];
	private static final String[] SPANISH = new String[6];
	private static final String[] FRENCH = new String[6];
	private static final String[] ITALIAN = new String[6];
	private static final String[] PORTUGESE = new String[6];

	public SystemCD() {

	}

	public SystemCD(Controller controller, String name, File file,
			Vector<SysDataFile> files) {
		SystemCD.controller = controller;
		this.s_name = name;
		this.s_file = file;
		this.s_documents = files;

	}

	/**
	 * Saves a given System CD File
	 * 
	 * @param fileToSave
	 *            The file to Save
	 */
	public void saveSysDataFile(SystemCD fileToSave) {
		JFileChooser fc = new JFileChooser();
		fc.setCurrentDirectory(new File("C:/test/SystemCD"));

		int returnVal = fc.showSaveDialog(null);
		if (returnVal == JFileChooser.APPROVE_OPTION) {

			ObjectOutputStream oos = null;
			FileOutputStream fos = null;

			try {
				fos = new FileOutputStream(fc.getSelectedFile()
						.getAbsolutePath() + ".sdata");
				oos = new ObjectOutputStream(fos);

				// Speichern des Objects
				oos.writeObject(fileToSave);

			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				// Prüfen ob die Streams geschlossen sind, wenn nicht, dann
				// werden
				// sie geschlossen
				if (oos != null)
					try {
						oos.close();
					} catch (IOException e) {
					}
				if (fos != null)
					try {
						fos.close();
					} catch (IOException e) {
					}
			}
		}
	}

	/**
	 * Saves a given System CD File
	 * 
	 * @param fileToLoad
	 *            The File to save
	 */
	public void loadSysDataFile() {
		JFileChooser fc = new JFileChooser();
		// Setz die den default Pfad
		fc.setCurrentDirectory(new File("C:/test/SystemCD"));
		// Setzen des FileFilter, so dass nur Dateiuen angezeigt werden, die mit
		// sData enden
		fc.setFileFilter(new FileFilter() {

			@Override
			public String getDescription() {
				return "System CD Data Files";
			}

			@Override
			public boolean accept(File f) {
				if (f == null)
					return false;

				// Ordner anzeigen
				if (f.isDirectory())
					return true;

				// true, wenn File gewuenschte Endung besitzt
				return f.getName().toLowerCase().endsWith(".sdata");
			}
		});
		int returnVal = fc.showOpenDialog(null);

		if (returnVal == JFileChooser.APPROVE_OPTION) {
			ObjectInputStream ois = null;
			FileInputStream fis = null;
			try {
				fis = new FileInputStream(fc.getSelectedFile()
						.getAbsolutePath());
				ois = new ObjectInputStream(fis);
				Object loadedObject = ois.readObject();
				// ist das geladene Object ein Object der SysData Klasse?
				if (loadedObject instanceof SystemCD) {
					SystemCD tmp = (SystemCD) loadedObject;
					// Setzen der geladenen SystemCD als aktive System cd
					controller.setCoreModel(tmp);
				}
				JOptionPane.showMessageDialog(null, "Laden erfolgreich");
			} catch (ClassNotFoundException e) {
				JOptionPane
						.showMessageDialog(
								null,
								"Datei konnte nicht geladen werden. Es gab ein Problem beim Laden der Datei",
								"Inane error", JOptionPane.ERROR_MESSAGE);
				e.printStackTrace();
			} catch (IOException e) {
				JOptionPane
						.showMessageDialog(
								null,
								"Datei konnte nicht geladen werden. Es gab ein Problem beim Laden der Datei",
								"Inane error", JOptionPane.ERROR_MESSAGE);
				e.printStackTrace();
			} finally {
				// Prüfen ob die Streams geschlossen sind
				if (ois != null)
					try {
						ois.close();
					} catch (IOException e) {
					}
				if (fis != null)
					try {
						fis.close();
					} catch (IOException e) {
					}
			}
		}
		if (returnVal == JFileChooser.CANCEL_OPTION) {
			return;
		}
	}

	/**
	 * Copies to given Files
	 * 
	 * @param in
	 *            The file to copy
	 * @param out
	 *            The Folder and Filename where it should be copied to
	 */
	public static void copyFiles(File in, File out) {
		FileChannel inChannel = null;
		FileChannel outChannel = null;
		try {
			inChannel = new FileInputStream(in).getChannel();
			outChannel = new FileOutputStream(out).getChannel();

			inChannel.transferTo(0, inChannel.size(), outChannel);
		} catch (IOException e) {
			JOptionPane.showMessageDialog(null,
					"The Files could not be copied", "Copy Error",
					JOptionPane.ERROR_MESSAGE);
			e.printStackTrace();
		} finally {
			// Streams schließen
			if (inChannel != null) {
				try {
					inChannel.close();
					outChannel.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}

	public static void createSystemCD() {
		// Holen der Dateien der aktuellen System CD
		Vector<SysDataFile> documents = controller.getCoreModel()
				.getDocuments();

		String share = "Z:/test/";

		File dir = new File(share + controller.getCoreModel().getName());
		dir.mkdir();

		// Schleife um die Dokumente diurchzugehen
		for (int i = 0; i < documents.size(); i++) {
			// Name vom alten Dokument, damit man es weiter verwenden kann
			String lang = getNameByLanguageId(documents.get(i).getLanguage());

			File dirTmp = new File(share + controller.getCoreModel().getName()
					+ "/" + lang);
			dirTmp.mkdir();

			String name = getLanguageAndType(controller.getCoreModel()
					.getDocuments().get(i).getLanguage(), controller
					.getCoreModel().getDocuments().get(i).getType());
			// Holt sich nach der Reihe die Dokumente und speichert sie dann im
			// gegebenen Pfad mit dem alten Namen ab

			copyFiles(documents.get(i).getFile(), new File(share + "/"
					+ controller.getCoreModel().getName() + "/" + lang + "/"
					+ name + ".pdf"));
		}
		JOptionPane.showMessageDialog(null, "System CD Created");
	}

	/**
	 * Returns the Type of the given Document
	 * 
	 * @param type
	 *            The Type of the Document as Integer
	 * @return The Type of the Document as String
	 */
	@SuppressWarnings("unused")
	private static String getTypeByTypeId(int type) {
		switch (type) {
		case 0:
			return "Bedienungsanleitung";
		case 1:
			return "Information";
		case 2:
			return "Datenblatt";
		case 3:
			return "Sicherheitsinformationen";
		case 4:
			return "Schnittstellenhinweis";
		case 5:
			return "Broschüre";
		default:
			return "Keine Angabe";
		}
	}

	/**
	 * Returns the Language of the given Document
	 * 
	 * @param language
	 *            The Document of the Document as integer
	 * @return the Language of the Document as String
	 */
	private static String getNameByLanguageId(int language) {
		switch (language) {
		case 0:
			return "Deutsch";
		case 1:
			return "Englisch";
		case 2:
			return "Spanisch";
		case 3:
			return "Italienisch";
		case 4:
			return "Portugiesisch";
		case 5:
			return "Französisch";
		default:
			return "Keine Angabe";
		}
	}

	public static String getLanguageAndType(int language, int type) {
		createArrays();
		return langArray[language][type];
	}

	private static void createArrays() {

		// Erzeugen der Arrays
		langArray[0] = GERMAN;
		langArray[1] = ENGLISCH;
		langArray[2] = SPANISH;
		langArray[3] = FRENCH;
		langArray[4] = ITALIAN;
		langArray[5] = PORTUGESE;

		// Deutsch
		GERMAN[0] = "Bedienungsanleitung";
		GERMAN[1] = "Datenblatt";
		GERMAN[2] = "Sicherheitsdatenblatt";
		GERMAN[3] = "Sicherheitsinfos";
		GERMAN[4] = "Broschüre";
		GERMAN[5] = "Information";

		// Englisch
		ENGLISCH[0] = "Instruction Manual";
		ENGLISCH[1] = "Data Sheet";
		ENGLISCH[2] = "Safety Information";
		ENGLISCH[3] = "Safety Infos";
		ENGLISCH[4] = "Brochure";
		ENGLISCH[5] = "Information";

		// Spanish
		SPANISH[0] = "Bedienungsanleitung - sp";
		SPANISH[1] = "Datenblatt - sp";
		SPANISH[2] = "Sicherheitsdatenblatt - sp";
		SPANISH[3] = "Sicherheitsinfos - sp";
		SPANISH[4] = "Broschüre - sp";
		SPANISH[5] = "Information - sp";

		// Französisch
		FRENCH[0] = "Bedienungsanleitung - fr";
		FRENCH[1] = "Datenblatt - fr";
		FRENCH[2] = "Sicherheitsdatenblatt - fr";
		FRENCH[3] = "Sicherheitsinfos - fr";
		FRENCH[4] = "Broschüre - fr";
		FRENCH[5] = "Information - fr";

		// Italienisch
		ITALIAN[0] = "Bedienungsanleitung - it";
		ITALIAN[1] = "Datenblatt - it";
		ITALIAN[2] = "Sicherheitsdatenblatt - it";
		ITALIAN[3] = "Sicherheitsinfos - it";
		ITALIAN[4] = "Broschüre - it";
		ITALIAN[5] = "Information - it";

		// Portugiesisch
		PORTUGESE[0] = "Bedienungsanleitung - por";
		PORTUGESE[1] = "Datenblatt - por";
		PORTUGESE[2] = "Sicherheitsdatenblatt - por";
		PORTUGESE[3] = "Sicherheitsinfos - por";
		PORTUGESE[4] = "Broschüre - por";
		PORTUGESE[5] = "Information - por";
	}

	/**
	 * @return the s_name
	 */
	public String getName() {
		return s_name;
	}

	/**
	 * @param s_name
	 *            the s_name to set
	 */
	public void setS_name(String s_name) {
		this.s_name = s_name;
	}

	/**
	 * @return the s_file
	 */
	public File getFile() {
		return s_file;
	}

	/**
	 * @param s_file
	 *            the s_file to set
	 */
	public void setS_file(File s_file) {
		this.s_file = s_file;
	}

	/**
	 * @return the s_documents
	 */
	public Vector<SysDataFile> getDocuments() {
		return s_documents;
	}

	/**
	 * @param s_documents
	 *            the s_documents to set
	 */
	public void setDocuments(Vector<SysDataFile> s_documents) {
		this.s_documents = s_documents;
	}
}

Wie man sieht lade ich in der Methode loadSysDataFile meine Datei und setzte dann im Controller die "Aktive" Datei.

Da kommt dann auch noch gleich mein zweites Problem dazu. Ich wollte die Methoden copy und load "static" machen, damit ich in meiner GUI Klasse einfach so auf die Methoden zugreifen kann und keine neue Instanz meiner SystemCD Klasse erstellen muss (wäre ja auch unnötig). Denn das Problem ist, wenn ich das Programm starte, ist ja keine Datei geladen --> Keine Instanz der Klasse --> Kein Zugriff auf die Methode. Also dachte ich mir ich mache sie static, jedoch will ich auch mit dem Observer Pattern arbeiten, damit sich die GUI Gescheit akutalisiert.
Jedoch laufen die Methoden notifyObserver() und update() nicht in einer statischen Methode. Hat da jemand eine Idee?
 
Hmm... Serializable... Objekte werden per ObjectOutputStream gespeichert und per ObjectInputStream wieder in die passende Klasse (sofern vorhanden) geladen. Was vom ObjectInputStream kommt muss allerdings explizit in die gewünschte Klasse gecastet werden. Die Daten befinden sich danach halt wieder in einer Instanz dieser Klasse und können dort auch wie gewohnt verwendet werden.
[EDIT]Die Antwort hat sich überschnitten... Du machst es ja bereits so. Was möchtest du denn da anders haben?
Zum Observer... Implementiere ein privates, statisches Observable und delegiere aus deiner Klasse auf die entsprechenden Methoden. Das ist im allgemeinen auch innerhalb einer Objektstruktur (also nicht statisch) sinnvoll, weil man nur so verhindern kann, dass Hinz und Kunz die Klasseneigenen Observer grundlos benachrichtigen. "notifyObservers()" musst du in deiner Klasse ja nicht nach aussen tragen).[/EDIT]
 
Zuletzt bearbeitet von einem Moderator:
Ich wollte wissen ob man es so macht, oder ob es dabei zu irgendwelchen Problemen kommen kann 😉 Aber wies aussieht hatte ich da ja schon einen guten Ansatz. Danke für deine Antworte. Dann kann ich da schonmal weiter arbeiten.

Vielleicht hat jemand noch ne Idee zu meiner zweiten Frage

Grüße
jh
 
Ich wollte die Methoden copy und load "static" machen, damit ich in meiner GUI Klasse einfach so auf die Methoden zugreifen kann und keine neue Instanz meiner SystemCD Klasse erstellen muss (wäre ja auch unnötig)

aber der Controller sollte doch eine Instanz deiner SystemCD-Klasse halten und die GUI eine Instanz des Controllers...=> die GUI sagt dem Controller diese Action ist ausgeführt worden...mach was und der Controller kann dann die entsprechenden Methoden aufrufen...
 
Ok ich glaub da gibt es noch ein paar Ungereimtheiten meinerseits was das MVC Pattern anbetrifft 😉
Hier mal meine Controller Klasse:
Java:
/**
 * 
 */
package mvc.controll;

import ui.CoreView;
import mvc.model.SystemCD;

/**
 * @author henrichj
 * 
 */
public class Controller {
	private CoreView coreView;
	private SystemCD coreModel;

	public Controller() {
		this.setCoreView(new CoreView(this));
		this.setCoreModel(new SystemCD(this));
	}

	public void showView() {
		coreView.setVisible(true);
	}

	public CoreView getCoreView() {
		return coreView;
	}

	public void setCoreView(CoreView coreView) {
		this.coreView = coreView;
	}

	public SystemCD getCoreModel() {
		return coreModel;
	}

	public void setCoreModel(SystemCD coreModel) {
		this.coreModel = coreModel;
	}
}

Und hier meine GUI: (Auf der Testweise nur ein Button drauf ist um das Laden zu testen)
Java:
package ui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;

import mvc.controll.Controller;

public class CoreView extends JFrame {

	/**
	 * 
	 */
	private static final long serialVersionUID = 4954083925326344054L;

	public CoreView(final Controller controller) {
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setBounds(0, 0, 1000, 400);

		JButton button = new JButton("laden");
		button.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				controller.getCoreModel().loadSysDataFile();
			}
		});
		add(button);
	}
}

Was meinst du damit das meine GUI eine Instanz vom Controller besitzt? Ich hab in meiner "Main" Klasse eine Instanz meines Controller angelegt.
Java:
/**
 * 
 */
package mvc.main;

import mvc.controll.Controller;

/**
 * @author henrichj
 * 
 */
public class Main {

	// Attribute
	static Controller controller;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		controller = new Controller();
		controller.showView();
	}

}

Oder meinst du das ich dann in meiner GUI sage:
controller.getModel().saveDatei()

Dann hätte ich es ja sogar verstanden. Werde es gleich mal testen 😉
 
Bei Daten aus Dateien - so diese komplett in den Speicher passen, halte ich diese i.d.R. als Liste von Datensatz-Objekten vor. Diese Datensatzobjekte haben für alle Einzeldaten eines Datensatzes dann Getter und Setter.
 
jo, sowas ist der Art...eigentlich -ohne den genauen Hintergrund deiner Anwendung zu kennen- sollte die GUI imho dem Controller nur mitteilen: "saveButtonPushed" und eine entsprechende Methode aufrufen...ob dieser dann sich das Model holt und dann die Datei saved, weiß einzig und alleine der Controller
 
Java:
class CoreView extends JFrame {

	/**
     * 
     */
	private static final long serialVersionUID = 4954083925326344054L;

	public CoreView(final Controller controller) {
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setBounds(0, 0, 1000, 400);

		JButton button = new JButton("laden");
		button.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				controller.saveButtonPushed();
			}
		});
		add(button);
	}
}

class Controller {
	private CoreView coreView;
	private SystemCD coreModel;

	public void saveButtonPushed(){
		coreModel.saveSysDataFile(fileToSave);
	}
 
Achso ja klar. Ich hab mal wieder um 19 Ecken gedacht 😉

Danke dir und den anderen erstmal. Leider ist bei mir noch ein weiteres Problem aufgetaucht. Ich wollte mal ein bisschen mit dem Observer Pattern rumspielen, hab dafür das hier gemacht:

Java:
package ui;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import mvc.controll.Controller;

public class CoreView extends JFrame implements Observer {

	private static final long serialVersionUID = 4954083925326344054L;
	private Controller controller;
	JLabel test;

	public CoreView(final Controller controller) {
		this.controller = controller;
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setBounds(0, 0, 1000, 400);

		JButton button = new JButton("laden");
		button.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				controller.getCoreModel().loadSysDataFile();
			}
		});

		add(button, BorderLayout.NORTH);
		test = new JLabel("test");
		add(test, BorderLayout.CENTER);
	}

	@Override
	public void update(Observable arg0, Object arg1) {
               // Holt den namen der geladenen Datei
              test.setText(controller.getCoreModel().getName();
	}
}

Zweiter Schritt:
Java:
/**
	 * Loads a given System CD File
	 * 
	 * @param fileToLoad
	 *            The File to load
	 */
	public void loadSysDataFile() {
		JFileChooser fc = new JFileChooser();
		// Setz die den default Pfad
		fc.setCurrentDirectory(new File("C:/test/SystemCD"));
		// Setzen des FileFilter, so dass nur Dateiuen angezeigt werden, die mit
		// sData enden
		fc.setFileFilter(new FileFilter() {

			@Override
			public String getDescription() {
				return "System CD Data Files";
			}

			@Override
			public boolean accept(File f) {
				if (f == null)
					return false;

				// Ordner anzeigen
				if (f.isDirectory())
					return true;

				// true, wenn File gewuenschte Endung besitzt
				return f.getName().toLowerCase().endsWith(".sdata");
			}
		});
		int returnVal = fc.showOpenDialog(null);

		if (returnVal == JFileChooser.APPROVE_OPTION) {
			ObjectInputStream ois = null;
			FileInputStream fis = null;
			try {
				fis = new FileInputStream(fc.getSelectedFile()
						.getAbsolutePath());
				ois = new ObjectInputStream(fis);
				Object loadedObject = ois.readObject();
				// ist das geladene Object ein Object der SysData Klasse?
				if (loadedObject instanceof SystemCD) {
					SystemCD tmp = (SystemCD) loadedObject;
					// Setzen der geladenen SystemCD als aktive System cd
					controller.setCoreModel(tmp);
		                        setChanged();
		                        notifyObservers();
				}
				JOptionPane.showMessageDialog(null, "Laden erfolgreich");
			} catch (ClassNotFoundException e) {
				JOptionPane
						.showMessageDialog(
								null,
								"Datei konnte nicht geladen werden. Es gab ein Problem beim Laden der Datei",
								"Inane error", JOptionPane.ERROR_MESSAGE);
				e.printStackTrace();
			} catch (IOException e) {
				JOptionPane
						.showMessageDialog(
								null,
								"Datei konnte nicht geladen werden. Es gab ein Problem beim Laden der Datei",
								"Inane error", JOptionPane.ERROR_MESSAGE);
				e.printStackTrace();
			} finally {
				// Prüfen ob die Streams geschlossen sind
				if (ois != null)
					try {
						ois.close();
					} catch (IOException e) {
					}
				if (fis != null)
					try {
						fis.close();
					} catch (IOException e) {
					}
			}
		}
		if (returnVal == JFileChooser.CANCEL_OPTION) {
			return;
		}
	}

Und dann natürlich noch den Observer angemeldet:
Java:
/**
 * 
 */
package mvc.controll;

import ui.CoreView;
import mvc.model.SystemCD;

/**
 * @author henrichj
 * 
 */
public class Controller {
	private CoreView coreView;
	private SystemCD coreModel;

	public Controller() {
		this.setCoreView(new CoreView(this));
		this.setCoreModel(new SystemCD(this));
		getCoreModel().addObserver(coreView);

	}

	public void showView() {
		coreView.setVisible(true);
	}

	public CoreView getCoreView() {
		return coreView;
	}

	public void setCoreView(CoreView coreView) {
		this.coreView = coreView;
	}

	public SystemCD getCoreModel() {
		return coreModel;
	}

	public void setCoreModel(SystemCD coreModel) {
		this.coreModel = coreModel;
	}
}

Wenn ich jetzt meine Datei lade. Dann setzt er auch brav das Label auf den Namen der in der Datei gespeichert ist. Drück ich nun noch einmal den "Laden" Button und lade eine andere Datei, ändert er mir den Namen nicht mehr. Ich hab auch Probehalber mal ein System.out.println() in die update() Methode geschrieben, und gesehen das die Methode nur beim ersten mal aufgerufen wird. Hat jemand dafür eine Erklärung?
 
Zuletzt bearbeitet:
Ich steig' da grad' nicht durch. Aber was mir auffällt: Du setzt ein neues CoreModel, kopierst aber die Observer des dadurch überschriebenen nicht. Möglich, dass die Observer ihren Zustand deswegen auch die Daten des alten CoreModels weiter verwenden.
 
extendet irgendeine Klasse Observable bei dir?
Jap und zwar die Klasse 'SystemCD' also quasi mein Model, sonst würde ja gar nichts passieren wenn ich eine neue Datei lade oder? Weil beim ersten mal setzt er das Textfeld ja richtig

Ich steig' da grad' nicht durch. Aber was mir auffällt: Du setzt ein neues CoreModel, kopierst aber die Observer des dadurch überschriebenen nicht. Möglich, dass die Observer ihren Zustand deswegen auch die Daten des alten CoreModels weiter verwenden.
Das kann natürlich sein, klingt sogar ziemlich logisch 🙂 Hast du nen Tipp wie ich die mitkopiere?

// Sorry zu spät gesehen 😛
 
Sorry zu spät gesehen 😛
Nee, war OK. 😉 und ähhh... Juhuuu sie funktioniert.
Okay... 'ne Idee zum Observable hatte ich ja weiter oben schon erwähnt. Folgendes: versuch' mal, an welchen stellen überall [c]controller.getCoreModel().notifyObservers()[/c] funktioniert. Du wirst feststellen: An sehr vielen und an den meisten davon sollte es eigentlich nicht gehen, kurzum, man kann das Observable von aussen beliebig traktieren. [c]notifyObservers()[/c] muss also "versteckt" bzw. protegiert werden. Darüber hinaus wäre SystemCD auch die falsche Klasse, die Observer erweitert, weil sich halt der komplette Klasseninhalt ändert bzw die Klasse stets neu instanziert wird. Der Controller ist dazu besser geeignet.
Also:
Java:
public class Controller extends UndSoWeiter {
  private final Observable observable = new Observable();

  // your code...

  public void addObserver(Observer obs) {
    observable.addObserver(obs);
  }

  public void removeObserver(Observer obs) {
    observable.removeObserver(obs);
  }

  /**
   * WICHTIG! kein Zugriffsmodifizierer. PackagePrivate!
   */
  void notifyObservers() {
    observable.notifyObservers();
  }
}
Solange SystemCD und Controller im selben Package liegen, kannst du aus SystemCD nun [c]controller.notifyObservers()[/c] aufrufen. In Klassen ausserhalb dieses Package hast du diese Option allerdings nicht mehr.
 
Danke dir für die Antwort. Ich werde es gleich morgen mal ausprobieren wenn ich wieder auf der Arbeit bin 🙂 Und melde mich dann gegebenenfalls nochmal
 

Zurück
Oben