Swing Datei lässt sich zwar speichern, aber nicht laden (Inhalt im JTextField anzeigen)

Alex2013

Bekanntes Mitglied
Hi Leute,

nach langer Zeit habe ich mich mal wieder an Java gesetzt und habe mich mit Dateien beschäftigt. Ich gebe über eine GUI in ein Textfeld etwas ein und speichere dies in einer Datei. Anschließend möchte ich den Inhalt dieser Datei laden und in ein andere Textfeld auf der gleichen GUI anzeigen lassen. Hier wird mir aber ein Fehler geworfen. Einige Varianten habe ich jetzt durch, aber einen Ansatz habe ich immer noch nicht.

Vlt. könnt ihr mir ja helfen bzw. einen Tipp geben.
Mein Code:

Hauptklasse:
Java:
import java.awt.Container;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.ProcessBuilder.Redirect;
import java.net.URL;
import java.util.Scanner;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

public class DateiErstellung extends JFrame implements ActionListener {
    
    ReadFile3 rf3;
    JButton speichern = new JButton("Speichern"), schliessen = new JButton(
            "Schliessen"), laden=new JButton("laden");
    JLabel name = new JLabel("Name: ", JLabel.RIGHT), wohnort = new JLabel(
            "Wohnort: ", JLabel.RIGHT), beruf = new JLabel("Beruf: ",
            JLabel.RIGHT);
    JTextField nameText = new JTextField(10), wohnortText = new JTextField(10),
            berufText = new JTextField(10);
    Container c;
    Font font = new Font("Name", Font.PLAIN, 18);

    public DateiErstellung() {
        setSize(400, 300);
        setLocationRelativeTo(null);
        setLayout(new GridLayout(4, 2));
        c = getContentPane();
        c.add(name);
        name.setFont(font);
        c.add(nameText);
        c.add(wohnort);
        wohnort.setFont(font);
        c.add(wohnortText);
        c.add(beruf);
        beruf.setFont(font);
        c.add(berufText);
        c.add(speichern);
        speichern.setFont(font);
        speichern.addActionListener(this);
        c.add(laden);
        laden.setFont(font);
        laden.addActionListener(this);
        c.add(schliessen);
        schliessen.setFont(font);
        schliessen.addActionListener(this);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        new DateiErstellung();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        File fw = new File("D:\\Dokumente\\Alexander\\Java\\Test\\test.txt");
        
        if (e.getSource() == speichern) {
            if (fw.exists() != true) {
                try {
                    fw.createNewFile();
                    System.out.println("Datei wurde erstellt");
                    JFileChooser speichernJFC = new JFileChooser();

                    int returnVal = speichernJFC.showSaveDialog(this);
                    if (returnVal == JFileChooser.APPROVE_OPTION) {
                        speichernJFC.setCurrentDirectory(fw);
                        try {
                            String words = nameText.getText() + " "
                                    + wohnortText.getText() + " "
                                    + berufText.getText();
                            BufferedWriter bw = new BufferedWriter(
                                    new FileWriter(fw, true));
                            bw.write(words + "\n");
                            bw.write(System.getProperty("line.separator"));
                            bw.close();
                            JOptionPane.showMessageDialog(null, "Datei: "
                                    + speichernJFC.getSelectedFile().getName()
                                    + " wird gespeichert", "Datei speichern",
                                    JOptionPane.INFORMATION_MESSAGE);
                        } catch (IOException e1) {
                            e1.printStackTrace();
                        }
                    } else
                        JOptionPane.showMessageDialog(null,
                                "Datei wurde nicht gespeichert", "Fehler",
                                JOptionPane.ERROR_MESSAGE);
                } catch (IOException aw) {
                    System.out.println(aw);
                }
            
            } else {
                JFileChooser speichernJFC = new JFileChooser();

                int returnVal = speichernJFC.showSaveDialog(this);
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    speichernJFC.setCurrentDirectory(fw);
                    try {
                        String words = nameText.getText() + " "
                                + wohnortText.getText() + " "
                                + berufText.getText();
                        BufferedWriter bw = new BufferedWriter(new FileWriter(
                                fw, true));
                        bw.write(words + "\n");
                        bw.write(System.getProperty("line.separator"));
                        bw.close();
                        JOptionPane.showMessageDialog(null, "Datei: "
                                + speichernJFC.getSelectedFile().getName()
                                + " wird gespeichert", "Datei speichern",
                                JOptionPane.INFORMATION_MESSAGE);
                    } catch (IOException e1) {
                        e1.printStackTrace();
                        System.out.println(e1);
                    }
                } else
                    JOptionPane.showMessageDialog(null,
                            "Datei wurde nicht gespeichert", "Fehler",
                            JOptionPane.ERROR_MESSAGE);
            }
            
        } else if (e.getSource() == schliessen) {
            this.dispose();
        }
        else if(e.getSource() == laden){
            
            ///Dies funktioniert nicht///
            ReadFile3 rf3 = null;
            
            ///Dies funktioniert auch nicht///
//            ReadFile3 rf3 = new ReadFile3();
            
            String txt=rf3.toString();
            
//                String str=txt.getContent().toString();
//                wohnortText.setText(str);
            
                wohnortText.setText(txt);
        }
    }
}

Datei wird gelesen:
Java:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

class ReadFile3
{
    @SuppressWarnings("null")
    public ReadFile3()
    {
        DateiErstellung de = null;
        File file =new File("D:\\Dokumente\\Alexander\\Java\\Test\\test.txt");
        
        Scanner s=null;
        try {
            s = new Scanner(file);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String zeile="";
        

        while( (zeile = s.nextLine()) != null )
        {
          de.beruf.setText(zeile);
        }

        s.close();
      }    
}

Was genau muss ich wo ändern, damit die Datei geladen werden kann?

Besten Dank im Voraus 🙂
 
Schreibe das komplette JTextField
Java:
		File file = null;

		JTextField nameText = new JTextField(10), wohnortText = new JTextField(10), berufText = new JTextField(10);
		try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file))) {
			oos.writeObject(nameText);
			oos.writeObject(wohnortText);
			oos.writeObject(berufText);
		} catch (IOException e1) {
			e1.printStackTrace();
		}

		try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
			nameText = (JTextField) ois.readObject();
			wohnortText = (JTextField) ois.readObject();
			berufText = (JTextField) ois.readObject();
		} catch (IOException | ClassNotFoundException e1) {
			e1.printStackTrace();
		}
 
Also ObjectInputStream und ObjectOutputStream zu nutzen kann ich ja noch nachvollziehen. Aber wozu ganze Controls speichern und laden, wenn man doch offensichtlich nur den Text der Elemente haben möchte?

Da wäre es dann schon ausreichend, einfach die Strings zu speichern und dann zu laden. (Dann würde das auch noch funktionieren, wenn man die Controls ändert - ist sonst eine unnötige Abhängigkeit. Zumal ich unsicher bin, ob die Controls nicht sogar eine Abhängigkeit der Version haben. Müsste man einfach mal ausprobieren: Schreiben mit java 8 und dann lesen mit java 11 ....)

Aber generell kann man sich auch überlegen, darauf ganz zu verzichten. Wenn da z.B. keine Zeilenumbrüche vorkommen können ("words" Variable), dann könnte man da auch einfach ein Wort pro Zeile schreiben. Dann hat man weiterhin eine lesbare Datei, die auch manuell anpassbar wäre. Und das lesen / schreiben kann man einfach über BufferedReader/ BufferedWriter machen mittels readLine / write,writeLine.
(siehe auch http://openbook.rheinwerk-verlag.de/javainsel9/javainsel_17_005.htm für nähere Informationen zum Lesen / Schreiben ...)
 
Das würde ich nicht empfehlen, ist ein anti pattern.

Also eine lesbare Datei zu schreiben ist ein Anti Pattern? Oder was ist ein Anti Pattern? Das würde mich einmal interessieren.

Selbstverständlich kann man ein vernünftiges Format zu Grunde legen. Und da spricht nun wirklich nichts gegen die Verwendung von Separatoren. Findet sich übrigens in sehr vielen Protokollen - man könnte ja mal die eine oder andere RFC lesen ... Also wahrlich kein "Anti Pattern".

Die properties Files machen es ja auch nicht groß anders. Nur eben, dass zu dem Wert noch ein Key kommt ...

Binary Serialisierung ist aber heutzutage das, was man eigentlich nicht mehr macht (nach meiner Erfahrung). Das bringt einfach zu viele Probleme mit sich. Mit der Zeit verändert sich einfach zu viel und man will Daten lesen und speichern können... Das ist ein Grund, warum ich äußerst ungerne zu einer Binary Serialisierung greife.

Heutzutage ist die Serialisierung über lesbare Formate doch durchaus üblich: XML, JSON, ...

Neue Felder sind kein Thema - die kann dann die alte Variante zur Not ignorieren. Umgekehrt entfallene Felder... Das macht XML und JSON sehr mächtig. Zusammen mit den Frameworks ist das dann auch etwas, das ohne eigenen Code abläuft. Aber das alles ist hier für einen Anfänger doch deutlich zu viel. Der TE soll die Grundlagen erst einmal verstehen und da ist so eine einfache Serialisierung, die er sich dann auch in einem Editor vernünftig anschauen kann, perfekt.
 
ich nehme mal an, sollten mehrere Textfelder vorhanden sein, dann - same procedure - für jedes
Ja, aber die kompletten Textfelder brauchst Du nicht serialisieren, Speichere die Strings zum Beispiel in einer Properties Datei, wenn diese in lesbarer form gespeichert werden sollen.

@JustNobody Das Anti-Pattern hat man sich (vor 40 Jahren) innerhalb der Datenbanken überlegt, wie sinnvoll es sei, Tabellen in Textdateien zeilenweise zu speichern.
 
Ich habe den Ansatz jetzt mal versucht.
Das Menü zum Laden habe ich hingebastelt, aber sobald ich die Datei wähle und "lade" wirft er eine Exception.

der code der entsprechenden Stelle sieht aktuell wie folgt aus:

Java:
else if(e.getSource() == laden){
            File file=null;//new File("D:\\Dokumente\\Alexander\\Java\\Test\\test.txt");
            
            JFileChooser ladenJFC = new JFileChooser();
            
            int returnLoad = ladenJFC.showOpenDialog(this);
            
            if (returnLoad == JFileChooser.APPROVE_OPTION) {
                ladenJFC.getName(fw);
                ladenJFC.setCurrentDirectory(fw);
                            
            
            try (ObjectOutputStream oos = new ObjectOutputStream(
                    new FileOutputStream(file))) {
                oos.writeObject(nameText);
                oos.writeObject(wohnortText);
                oos.writeObject(berufText);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            
            
            try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
                    file))) {
                nameText = (JTextField) ois.readObject();
                wohnortText = (JTextField) ois.readObject();
                berufText = (JTextField) ois.readObject();
            } catch (IOException | ClassNotFoundException e1) {
                e1.printStackTrace();
            }
        }

ggf. noch einen Tipp, wie ich das Menü zum laden der Datei umbauen muss?
 
Java:
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
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 javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

public class Felder {
	private JTextField f1 = new JTextField();
	private JTextField f2 = new JTextField();
	private JTextField f3 = new JTextField();
	private JButton b1 = new JButton("Save");
	private JButton b2 = new JButton("Load");

	public Felder() {
		JFrame f4 = new JFrame();
		f4.setLayout(new GridLayout(2, 3));
		f4.add(f1);
		f4.add(f2);
		f4.add(f3);
		f4.add(b1);
		f4.add(b2);
		f4.pack();
		f4.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		f4.setVisible(true);

		b1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				JFileChooser jfc = new JFileChooser();
				int o = jfc.showSaveDialog(null);
				if (o == JFileChooser.APPROVE_OPTION) {
					File file = jfc.getSelectedFile();
					try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file))) {
						oos.writeObject(f1.getText());
						oos.writeObject(f2.getText());
						oos.writeObject(f3.getText());
					} catch (IOException e1) {
						e1.printStackTrace();
					}
				}
			}
		});

		b2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				JFileChooser jfc = new JFileChooser();
				int o = jfc.showOpenDialog(null);
				if (o == JFileChooser.APPROVE_OPTION) {
					File file = jfc.getSelectedFile();
					// ...check if File exists...
					try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
						f1.setText((String) ois.readObject());
						f2.setText((String) ois.readObject());
						f3.setText((String) ois.readObject());
					} catch (IOException | ClassNotFoundException e1) {
						e1.printStackTrace();
					}
				}
			}
		});
	}

	public static void main(String[] args) {
		Felder felder = new Felder();
	}
}
 
@JustNobody Das Anti-Pattern hat man sich (vor 40 Jahren) innerhalb der Datenbanken überlegt, wie sinnvoll es sei, Tabellen in Textdateien zeilenweise zu speichern.

Sorry, aber hier speicherst Du UI Controls....

Ist bestimmt eine ganz neue Entwicklung, dass man jetzt UI so mit Daten verknüpft, so dass diese sogar fürs Speichern verwendet wird.... Ja, damals war das alles viel komplexer - da hat man noch Model und UI getrennt gehalten und so....

Bei so Qualitativen Threads sollte ich mich auch einfach raushalten ... Dieser "Tobias-Clean-Code" ist halt etwas, das ich nicht beherrsche... Aber es gibt bestimmt Regeln bezüglich f1-f3 JTextFields und f4 ein JFrame und so ... Aber musst Du jetzt nicht erläutern, da ich das eh nicht verstehe ...

Also frickelt mal schön weiter - ich halte mich hier jetzt raus zumal Du ja auf einer Wellenlänge mit dem TE zu sein scheinst 🙂
 
Danke dass Du Dich heraushältst, das erleichtert die Kommunikation mit dem TE ungemein. Und naja, für Wissenslücken kann ich nichts.
 
Ich habe bisher zwar in der IT gearbeitet, aber mit Programmierung direkt im professionellen Umfeld noch nichts zu tun gehabt. Höchstens etwas skripten.

Wissenschaftler? Ich nehme mal an im Bereich Mathematik und Informatik?
 
@Alex2013 Ist das denn eine Thematik, die du weiter vertiefen möchtest? Oder war das nur eine Spielerei, bei der du es belassen möchtest?
 
So hier und da sicher mal vertiefen @JustNobody

aber um das professionell betreiben z können, fehlen wahrscheinlich schon sichere Grundkenntnisse auf die man wirklich aufbauen kann. Daher das wohl nicht.

Aber sehr interessant ist es allemal und Programmieren an sich und Kenntnisse darin zu haben (im Programmieren) ist sicher auch in vielerlei Hinsicht hilfreich!
 
Hättest Du gleich gesagt, noch keinerlei Erfahrungen zu haben so hätte ich anders geantwortet. 😉
 
@Tobias-nrw : das ist auch nicht ganz richtig. Ich habe schon öfter mal ein bisschen was programmiert. Aber eben nicht kommerziell sondern um meine Kenntnisse zu verbessern. Ich habe auch ein Buch über Java zu Hause. Aber ich beschäftige mich damit im Moment ausschließlich privat und in meiner Freizeit. Und ich denke, so wie es aussieht, wird es dabei auch bleiben. Es ist zwar auch (hoch) interessant, aber für den professionellen Einsatz werden meine Kenntnisse bei Weitem noch nicht ausreichen ;-)

Aber ich arbeite gerne daran meine Kenntnisse zu verbessern und zu erweitern 🙂
 
Das interpretiere ich jetzt so, dass Du das, was Du da bisher so "gescriptet" (*) hast nicht auf ordentliche Füße stellen willst. (Zumal da ja noch nichts wirkliches enthalten ist. Du hast Controls mit irgendwelchen Daten aber die Daten sind derzeit noch ohne Sinn und so.

Das was bei einer objektorientierten Entwicklung macht ist halt, dass man sich ein Model aufbaut. Bei diesem Model achtet man dann auf gewisse Dinge - so hält man z.B. Business-Logik getrennt von der eigentlichen UI. (Hat viele Gründe, auf die ich erst einmal nicht weiter eingehen möchte.)

Das könnte man behandeln. Ebenso der Punkt, bei dem ich die Auseinandersetzung mit Tobias hatte. Diese Speicherung, die Du nun hast, hat gewisse Nachteile, weshalb ich diesbezüglich eigentlich niemanden kenne, der das noch wirklich einsetzt...

(*) Dieses gescriptet dient nicht als Wertung sondern drückt einfach nur aus, was man da halt sieht: Wie ein Script ist das aufgebaut. Alle schön zusammen, keine Objektorientierung, Alles einfach zusammengeschmissen.... (Wobei das sehr vereinfacht dargestellt ist und eine stark vereinfachte Darstellung nutzt. Halt reine "Umgangssprache".)
 

Zurück
Oben