TextArea: schreiben/lesen

321

Grünschnabel
Hi Leute! :)

So, muss jetzt wirklich fragen- es hilft nichts... :(
Sitz nun schon seit 2 Tagen und komm ned weiter. Das einzige was passiert ist, dass sich mein armes Vaio mit 1 GB RAM und 1,73 GHz den Gar ausmacht!?
CPU- Auslastung bei 100%- dürfte eine Endlosschleife beim Lesen bzw. Schreiben auslösen... der Grund ist mir jedoch ned klar!? :eek:

Hab ein "JFrame" mit einer "TextArea" erzeugt. Die 2 "JMenuItems" sind "Öffnen" und "Speichern".

Beim "Öffnen" soll der Text einer *.txt- Datei in meiner "TextArea" angezeigt werden und bei "Speichern" soll der Text, den ich in meine "TextArea" geschrieben hab, in eine *.txt- Datei gespeichert werden.

Der Einfachbarkeit halber verwende ich einen "FileDialog".

Hab das GUI vom Verwalten der Datei getrennt. Mir ist das MVC- Konzept noch nicht so geläufig- aber das glaub ich wird schon...

Beim "GUI" hab ich ein Datenfeld vom Typ "TextArea", auf das ich mit der 2ten Klasse "DateiVerwalter" zugreife.

Dieses Datenfeld ist jetzt noch public- es geht mir jetzt nur mal um das richtige Funktionieren.

Später werde ich dann eh mittels sondierenden/verändernden Methoden darauf zugreifen bzw. gleich eine komlett neue Klasse nur für die "TextArea" schreiben und diese dann mit dem "DateiVerwalter" belesen/beschreiben und anschließend dem "GUI" übergeben.

Hmm... ist "DateiVerwalter" dann meine "Logische Einheit"? :confused:

------------------------------------------------------------------------------------------

Code:
public void öffne()
	{
		FileDialog fd = new FileDialog(frame, "Öffnen", FileDialog.LOAD);
		fd.setFile("*.txt");
		fd.setVisible(true);
		
		String s1 = fd.getDirectory() + fd.getFile();
		File f1 = new File(s1);
		
		BufferedReader reader = null;
		
		if(f1 != null){
			
			frame.textArea.selectAll();
			frame.textArea.replaceRange("", frame.textArea.getSelectionStart(), //clear textArea
					frame.textArea.getSelectionEnd());
		}
			try{
				reader = new BufferedReader(new InputStreamReader(new FileInputStream(f1)));
				String textIn;
				textIn = reader.readLine();
				
				while(textIn != null){
					frame.textArea.append(textIn + "\n");
					textIn = reader.readLine();
				}
				reader.close();
			}
			catch(FileNotFoundException e){
				System.out.println("Datei nicht gefunden" + e);
			}
			catch(IOException e){
				System.out.println("Lesefehler" + e);
			}
		}
Code:
public void speichere()
	{
		FileDialog fd = new FileDialog(frame, "Speichern", FileDialog.SAVE);
		fd.setFile("*.txt");
		fd.setVisible(true);
		
		String s2 = fd.getDirectory() + fd.getFile();
		File f2 = new File(s2);
		
		if(fd.getFile() != null)
		{
			BufferedWriter writer = null;
		
			try{
				writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f2)));
				
				String textOut = frame.textArea.getText();
				
				while(textOut != null){
					writer.write(textOut);
					textOut = frame.textArea.getText();
				}
				writer.close();
			}
			catch(FileNotFoundException e)
			{
				System.out.println("Fehler beim Speichern" + e);
			}
			catch(IOException e)
			{
				System.out.println("Schreibfehler..." + e);
			}
		}
	}

In "DateiVerwalter" hab ich mein "GUI" als konstante Klassenvariable ("static final") drin stehen und erzeuge eine neue Instanz davon (frame) und im "GUI" hab ich einen "DateiVerwalter" als konstante Klassenvariable drin stehen, der natürlich mit "new" initialisiert werden muss.

Außerdem habe ich im "GUI" eine "TextArea" (textArea) als öffentliches Datenfeld stehen. (vorerst nur zum Testen ob es geht) :p

deswegen: "frame.textArea"

--------------------------------------------------------------------------------------------

thx && greets, David
 
100% Auslastung bedeutet in diesem Fall vermutlich wirklich eine Endlosschleife. Die beiden while-Schleifen kommen dafür in Frage. Am einfachsten ist es, wenn Du durch den Code debuggst.
 
Hallo David,

hier ein kleines Beispiel:

Java:
import java.awt.*;
import java.awt.event.*;
import java.io.*;

import javax.swing.JTextArea;

public class OpenAndSaveInAWT extends Frame implements ActionListener {
	private static PrintStream o = System.out;

	private TextArea tArea = new TextArea();

	private FileDialog openDialog = new FileDialog(this, "Open", FileDialog.LOAD);

	private FileDialog saveDialog = new FileDialog(this, "Save", FileDialog.SAVE);

	private Button openBtn = new Button("Open");

	private Button saveBtn = new Button("Save");

	private ReadandWriteHelpTool helpTool = new ReadandWriteHelpTool();

	public OpenAndSaveInAWT() {
		super("Open and Save in AWT Example");
		this.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		this.setSize(400, 500);
		this.setLocationByPlatform(true);

		openBtn.addActionListener(this);
		saveBtn.addActionListener(this);

		this.add(openBtn, BorderLayout.NORTH);
		this.add(tArea, BorderLayout.CENTER);
		this.add(saveBtn, BorderLayout.SOUTH);

		this.setVisible(true);
	}

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

	public void actionPerformed(ActionEvent e) {
		if (e.getActionCommand().equals("Open"))
			open();
		else
			save();

	}

	public void open() {
		openDialog.setVisible(true);

		File file;
		if (openDialog.getFile() != null) {
			file = new File(openDialog.getFile());
			try {
				helpTool.read(new FileReader(file), null);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			tArea.setText(helpTool.getText());
		}
	}

	public void save() {
		saveDialog.setVisible(true);

		File file;
		if (saveDialog.getFile() != null) {
			file = new File(saveDialog.getDirectory(),saveDialog.getFile() + ".txt");
			try {
				helpTool.setText(tArea.getText());
				helpTool.write(new FileWriter(file));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	class ReadandWriteHelpTool extends JTextArea {
	}
}


Vg Erdal
 
Zuletzt bearbeitet:
@flashray Wow, danke! :)

Was machst du mit:
Code:
 private ReadandWriteHelpTool helpTool = new ReadandWriteHelpTool();
Wieso erzeugst du ein neues "ReadandWriteHelpTool"- Objekt?

Und wieso steht unten:
Code:
class ReadandWriteHelpTool extends JTextArea {
    }
Wieso erbt dein "ReadandWriteHelpTool" von der Klasse "JTextArea"?


Wo hast du den Code her und wie machst du das mit der "allin URL"- mit den Links zum Draufklicken für Google? ;)

Welche Entwicklungsumgebung verwendest du? Eclipse? :)

Mein Problem von vorher:


Es funktioniert in der Konsole, wenn ich
Code:
frame.textArea.append(textIn + "\n");
durch
Code:
System.out.println(textIn + '\n');
ersetze.
Und wenn ich
Code:
frame.textArea.getText();
durch
Code:
String textOut = "blablabla";
ersetze, wird der "String" in die angegebene Datei geschrieben.

Die Endlosschleife hab ich da:
Code:
while(textOut != null){
  writer.write(textOut);
  textOut = frame.textArea.getText();
}

Die Methode ".getText()" schreibt ja den gesamten Text auf einmal- nicht zeilenweise wie beim Lesen... ;)

Also muss das Problem eindeutig an der "TextArea" liegen!? :suspekt:

Weiß nicht so recht, wie ich das richtig implementieren soll.

Danke, David :)
 
Hallo David,

1.)

private ReadandWriteHelpTool helpTool = new ReadandWriteHelpTool();
class ReadandWriteHelpTool extends JTextArea {
}

dieses helpTool ist nichts weiteres als ein Objekt der Klasse JTextArea. Die Klasse JTextArea hat die Methoden read() und write() mit denen man einfach mit einem FileReader und FileWriter den gesamten Text auf einmal lesen und schreiben. Diese Methoden sind deswegen zu Empfehlen da es mit einer Schleife schwierig ist einen Text vollständig ein und auszulesen. Wenn der Text am Anfang oder Ende ein oder mehrere Leerzeilen hat, kommt es bei einer Zeilenweisen Abarbeitung vor das die eine oder andere Leerzeile entweder fehlt oder zuviel ist.

Das TextArea hingegen hat keine read() und write() Methoden. Da du für deine GUI AWT-Komponenten verwendest, wollte ich keine Swingkomponente direkt zuhilfenehmen. Mit dieser leeren Klasse welche von JTextArea erbt habe ich dies verstecken wollen ;) . Du könntest natürlich auch:

JTextArea helpTool = new JTextArea()

benutzen.

2.)

das mit den allin URL ist nichts besonderes. Statt [ CODE ] [ / CODE ] verwende [ JAVA ] [ / JAVA ] :) .

3.)

Ja ich nutze Eclipse

4.)

Schau mal hier, wie die richtige Anwendung von read und write aussehen könnte:

http://javaalmanac.com/egs/java.io/ReadLinesFromFile.html
http://javaalmanac.com/egs/java.io/WriteToFile.html?l=rel

An der TextArea gibt es keine Probleme, du verwendest es einfach nicht richtig.


Allerdings würde ich, wie oben schon erwähnt, die read() und write() Methoden von JTextArea zuhilfenehmen, da es bei einer Zeilenweisen ein und auslesung Probleme mit zuvielen oder fehlenden Leerzeilen geben kann.

Wieso verwendest du eigentlich AWT, nimm lieber Swing, wenn nichts dagegensteht.

Schau dir auch mal das Online Buch Java Insel an:
http://www.galileocomputing.de/openbook/javainsel5/

Beispielsweise das Kapitel Datenströme und Dateien. Da wirst du anhand vieler Beispiele mehr über das Lesen und Schreiben in JAVA erfahren.
http://www.galileocomputing.de/openbook/javainsel5/javainsel12_000.htm#Xxx999378


Vg Erdal
 
Zuletzt bearbeitet:
Danke sehr! :)

Verwende ja eh die Swing- Komponenten- hab ja als GUI ein JFrame. Setzt Swing nicht auf AWT auf?

Naja- wollte nur nicht die JTextArea verwenden, weil es da keinen Scrollbalken gibt... ;)
Muss ja dann die JTextArea in ein JScrollPane integrieren.

thx, David
 
Hallo David,

ein kleiner Hinweis: Man sollte AWT und Swingkomponenten nicht gemeinsam verwenden. Daraus können ungewünschte effekte entstehen. Entweder baust du deine GUI nur aus AWTkomponenten oder nur aus Swing.

Schmeiß lieber die TextArea aus deiner GUI rauß, falls der Rest Swing ist.
Nichts einfacher als eine JScrollPane:

JTextArea tArea = new JTextArea();
JScrollPane sPane = new JScrollPane(tArea);
myJFrame.add(sPane);

das wars schon.

Vg Erdal
 
Hallo David,

als ergänzung, in Swing würde das Beispielsweise so aussehen:

Java:
import java.awt.*;
import java.awt.event.*;
import java.io.*;

import javax.swing.*;

public class OpenAndSaveSwing extends JFrame implements ActionListener {
	private static PrintStream o = System.out;

	private JTextArea tArea = new JTextArea();
	
	private JScrollPane sPane = new JScrollPane(tArea);

	private JFileChooser fChooser = new JFileChooser();

	private JButton openBtn = new JButton("Open");

	private JButton saveBtn = new JButton("Save");
	
	private JPanel btnPanel = new JPanel();

	public OpenAndSaveSwing() {
		super("Open and Save in Swing Example");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setSize(400, 500);
		this.setLocationByPlatform(true);
		this.setAlwaysOnTop(true);

		GridLayout gl = new GridLayout(1,2);
		btnPanel.setLayout(gl);
		btnPanel.add(openBtn);
		btnPanel.add(saveBtn);
		
		openBtn.addActionListener(this);
		saveBtn.addActionListener(this);
		
		tArea.setLineWrap(true);
		tArea.setWrapStyleWord(true);

		// Falls du das vertikale ScrollBalken immer sehen möchtest
		//sPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		
		this.add(sPane, BorderLayout.CENTER);
		this.add(btnPanel, BorderLayout.SOUTH);

		this.setVisible(true);
	}

	public static void main(String[] args) {
		try {
			UIManager
					.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
		} catch (Exception e) {
		}
		new OpenAndSaveSwing();
	}

	public void actionPerformed(ActionEvent e) {
		if (e.getActionCommand().equals("Open"))
			open();
		else
			save();
	}

	public void open() {
		int result = fChooser.showOpenDialog(this);

		File file;
		if (result == JFileChooser.APPROVE_OPTION) {
			file = fChooser.getSelectedFile();
			try {
				tArea.read(new FileReader(file), null);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public void save() {
		int result = fChooser.showSaveDialog(this);

		File file;
		if (result == JFileChooser.APPROVE_OPTION) {
			file = fChooser.getSelectedFile();
			if (!file.getAbsolutePath().endsWith(".txt"))
				file = new File(file.getAbsolutePath() + ".txt");
			try {
				tArea.write(new FileWriter(file));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

Vg Erdal
 
Hallo Erdal!

Das heißt bei meinem GUI muss ich ein neues Datenfeld vom Typ "OpenAndSaveSwing" einfügen und dann im Konstruktor ein neues "OpenAndSaveSwing"- Objekt erstellen, mit Hilfe dessen Methoden ich dann mit meinem GUI lesen und schreiben kann? -sehr fein- :D

thx && greets, David ;)
 
Hallo David,

du musst nichts, aber du darfst wenn du möchtest :) . Allerdings wird es ein kleines Problem geben. Die Methoden aus der Klasse OpenAndSaveSwing öffnen und speichern den Text in und von der eigenen Textkomponente nämlich der tArea :) .

Ich schreibe zur Zeit auch einen kleinen Texteditor, so in die Richtung habe ich das auch bei mir implementiert. Habe auch eine ganze Weile mich mit der korrekten Implementierung einer Schleife die Text liest und schreibt rumgeärgert. Vor ca. zwei Monaten habe ich dann hier ins Forum geschrieben:

http://www.tutorials.de/forum/java/237047-text-aus-datei-eine-jtextarea-einlesen.html

und meine bekanntschaft mit myJTextArea.read() and write() gemacht. Ich gebe das weiter, was ich von den anderen Usern gelernt habe. Wenn jemand nach zwei drei Monaten dieselbe Frage stellt, wirst du ihm ein kleines Beispielprogrammschen schreiben "müssen" und er wird wohl die Methoden deines Beispiels nehmen "müssen" ;) .


Vg Erdal
 

Neue Beiträge

Zurück