Bloco de Notas
Este exemplo pretende demonstrar a utilização de Streams processadas para a escrita de texto e uma utilização simples de streams de memória para a implementação de um sistema de undo/redo. São mostrados apenas os métodos relevantes, podem ver todo o código nos vários ficheiros no fundo da página.
//...
public class BlocoNotas extends javax.swing.JFrame {
//Guarda o estado do documento para undo e redo
private transient ByteArrayOutputStream[] undos;
private int indice;
private static final int MAX_UNDO = 16;
private File ficheiro;
public BlocoNotas() {
initComponents();
undos = new ByteArrayOutputStream[BlocoNotas.MAX_UNDO];
for (int i = 0; i < BlocoNotas.MAX_UNDO; i++) {
undos[i] = new ByteArrayOutputStream();
}
indice = -1;
}
/**
* Permite abrir um ficheiro de texto, ler o seu conteúdo e preencher a
* JTextArea com o texto.
*
* @param file Ficheiro a abrir
*/
private void openDocument(File file) {
BufferedReader bf = null;
try {
bf = new BufferedReader(new FileReader(file));
String linha;
StringBuffer buf = new StringBuffer();
while ((linha = bf.readLine()) != null) {
buf.append(linha);
buf.append("n");
}
jtaText.setText(buf.toString());
ficheiro = file;
} catch (FileNotFoundException ex) {
JOptionPane.showMessageDialog(this, "Não foi possível encontrar o ficheiro "
+ file.getAbsolutePath(), "Ficheiro não encontrado.", JOptionPane.ERROR_MESSAGE);
} catch (IOException ex) {
JOptionPane.showMessageDialog(this, "Ocorreu um erro ao tentar ler o conteúdo do ficheiro.",
"Erro de leitura.", JOptionPane.ERROR_MESSAGE);
} finally {
if (bf != null) {
try {
bf.close();
} catch (IOException ex) {
//IGNORE
}
}
}
}
/**
* Permite gravar o conteúdo da JTextArea, num ficheiro já aberto ou num novo
* ficheiro se o documento é novo.
*/
private void saveDocument() {
if (ficheiro == null) {
JFileChooser jfc = new JFileChooser();
if (jfc.showSaveDialog(this) != JFileChooser.APPROVE_OPTION) {
return;
}
ficheiro = jfc.getSelectedFile();
}
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter(ficheiro));
bw.write(jtaText.getText());
} catch (IOException ex) {
JOptionPane.showMessageDialog(this, "Ocorreu um erro ao tentar gravar o documento.",
"Erro de escrita.", JOptionPane.ERROR_MESSAGE);
} finally {
if (bw != null) {
try {
bw.close();
} catch (IOException ex) {
//IGNORE
}
}
}
}
private void undo() {
ObjectInputStream is = null;
try {
is = new ObjectInputStream(new BufferedInputStream(new ByteArrayInputStream(undos[(--indice) % MAX_UNDO].toByteArray())));
String texto = (String) is.readObject();
jtaText.setText(texto);
} catch (ClassNotFoundException ex) {
//Nunca pode acontecer
System.err.println("Não foi possível fazer undo.");
System.err.println(ex.getMessage());
} catch (IOException ex) {
System.err.println("Não foi possível fazer undo.");
System.err.println(ex.getMessage());
} finally {
if (is != null) {
try {
is.close();
} catch (IOException ex) {
//IGNORE
}
}
}
}
private void redo() {
ObjectInputStream is = null;
try {
is = new ObjectInputStream(new BufferedInputStream(new ByteArrayInputStream(undos[(++indice) % MAX_UNDO].toByteArray())));
String texto = (String) is.readObject();
jtaText.setText(texto);
} catch (ClassNotFoundException ex) {
//Nunca pode acontecer
System.err.println("Não foi possível fazer redo.");
System.err.println(ex.getMessage());
} catch (IOException ex) {
System.err.println("Não foi possível fazer redo.");
System.err.println(ex.getMessage());
} finally {
if (is != null) {
try {
is.close();
} catch (IOException ex) {
//IGNORE
}
}
}
}
/**
* Guarda o stado no array de estados para undo/redo
*/
private void store() {
ObjectOutputStream os = null;
try {
undos[(++indice) % MAX_UNDO].reset();
os = new ObjectOutputStream(new BufferedOutputStream(undos[(indice) % MAX_UNDO]));
os.writeObject(jtaText.getText());
} catch (IOException ex) {
System.err.println("Não foi possível guardar o stado.");
System.err.println(ex.getMessage());
} finally {
try {
if (os != null) {
os.close();
}
} catch (IOException ex) {
//IGNORE
}
}
}
//...
}