Newsgroup: it.comp.java
Titolo: Problema con JTextArea e JScrollPane

Ciao a tutti
Sono un neofita e sto cercando ancora di capire come funziona usenet. 
Ho un problema con il componente JTextArea e spero che qualcuno di voi
possa aiutarmi... ho cercato in post precedenti ma nn ho trovato
niente... spero cmq di nn creare troppo problemi.
Passo dunque a spiegarmi l mio problema.. Devo realizzare una
"consolle" per una applicazione che sto sviluppando. Tale consolle
riceve input e fornisce in output le risposte dell'applicazione.
Ora però il problema è che il numero di output inviate alla consolle
spesso è elevato... facendo cosi consumaere alla applicazione una
quantita enorme di memoria. (E' capitato che venisse generata
l'eccezzione OutOfMemoryException). Combinando infatti  JScrollPane e
JTextArea vengono mantenute in memoria tutte le linee inviate alla
consolle... vorrei fare in modo appunto che lo scrollpane agisse solo
su un numero limitato di righe di testo e quindi memorizzare solo le
ultime 200 righe generate, in modo da risparmiare cosi memoria.
Per farvi capire vi copio il codice della funzione che uso io per
aggiungere una riga alla consolle:
   public void output(String str) {
      // aggiunge la righa all'area testo
      output.append(" "+str+"\r\n");
      // controlla se nn è stato raggiunto il limite della consolle
      while (output.getLineCount()>=200) {
         try {
            String testo;
            testo = output.getText();
            testo = testo.substring(output.getLineEndOffset(0));
            output.setText(testo);
         }
         catch (BadLocationException e) {
         }
      }
      // posiziona il cursore all'ultima liena generata
      // (modifica la posizione della scroll bar)
      output.setCaretPosition(output.getDocument().getLength());
   }
Il metodo funziona solo che l'effetto grafico nn è dei migliori
(vengono generati degli sfarfallamenti). Vorrei sapere se esise un
modo piu elegante e piu efficiente per risolvere il mio problema.
Grazie dell'attenzione ^_^

 modo piu elegante e piu efficiente per risolvere il mio problema.
Ciao,
si, esiste. Al posto di "lavorare" tramite la textArea agisci direttamente sul 
modello(Document); la differenza č sostanziale, l'esempietto che trovi allegato 
sulla mia macchina da questi risultati(dove 1) corrisponde alla textArea e 2) al 
document).
1) 6485 ms
1) 6359 ms
1) 6422 ms
1) 6234 ms
2) 547 ms
2) 625 ms
2) 360 ms
2) 610 ms
Se vuoi saperne di piů leggiti questo(complicatissimo!) articolo
http://java.sun.com/products/jfc/tsc/articles/text/element_buffer/index.html
Marco
///////////////////////////////////////////////////////
import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Test3 {
     final static JTextArea output = new JTextArea();
     public static void main(String[] args) {
         final StringBuffer buffer = new StringBuffer();
         for (int i = 0; i < 40; i++) {
             buffer.append('a');
         }
         JButton start1 = new JButton("Start1");
         start1.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) {
                 Thread thread = new Thread() {
                     public void run() {
                         long start = System.currentTimeMillis();
                         for (int i = 0; i < 1000; i++) {
                             output(i + " " + buffer.toString());
                         }
                         System.out.println("1) " +
                             (System.currentTimeMillis() - start) + " ms");
                     }
                 };
                 thread.start();
             }
         });
         JButton start2 = new JButton("Start2");
         start2.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) {
                 Thread thread = new Thread() {
                     public void run() {
                         long start = System.currentTimeMillis();
                         for (int i = 0; i < 1000; i++) {
                             output2(i + " " + buffer.toString(), 200);
                         }
                         System.out.println("2) " +
                             (System.currentTimeMillis() - start) + " ms");
                     }
                 };
                 thread.start();
             }
         });
         JButton clear = new JButton("Clear");
         clear.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) {
                 try {
                     output.getDocument().remove(0,
                         output.getDocument().getLength());
                 } catch (BadLocationException ble) {
                     System.out.println(ble);
                 }
             }
         });
         JPanel panel = new JPanel();
         panel.add(start1);
         panel.add(start2);
         panel.add(clear);
         JFrame frame = new JFrame();
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(new JScrollPane(output));
         frame.getContentPane().add(panel, BorderLayout.SOUTH);
         frame.setSize(400,200);
         frame.setVisible(true);
     }
     public static void output(String str) {
         output.append(" "+str+"\r\n");
         while (output.getLineCount()>=200) {
             try {
                 String testo;
                 testo = output.getText();
                 testo = testo.substring(output.getLineEndOffset(0));
                 output.setText(testo);
             }
             catch (BadLocationException e) {
             }
         }
         output.setCaretPosition(output.getDocument().getLength());
     }
     public static void output2(String str, int MAX_LINES) {
         output.append(str + System.getProperty("line.separator"));
         Document doc = output.getDocument();
         int linesCount = doc.getDefaultRootElement().getElementCount();
         if (linesCount > MAX_LINES) {
             int linesToRemove = linesCount - MAX_LINES;
             try {
                 Element root = doc.getDefaultRootElement();
                 Element element = root.getElement(linesToRemove);
                 int offset = element.getStartOffset();
                 doc.remove(0, offset);
             } catch (BadLocationException ble) {
                 System.err.println(ble);
             }
         }
         output.setCaretPosition(output.getDocument().getLength());
     }
}
-- 
reply: remove duh.spam.
http://javac.imap.cc

Se vuoi saperne di più leggiti questo(complicatissimo!) articolo

Grande!!! funziona tutto alla perfezione! ^_^ 
Ti ringrazio di cuore!!! 
Simone