Ir para o conteúdo

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
            }
        }
    }

//...
}