2009-03-10 9 views
23

Sto cercando di creare un'interfaccia utente Swing molto semplice che registri le informazioni sullo schermo tramite un JTextArea mentre l'elaborazione avviene in background. Quando l'utente fa clic su un pulsante, desidero ogni chiamata a:Aggiorna dinamicamente JTextArea mentre si verifica l'elaborazione?

textArea.append(someString + "\n"); 

per visualizzare immediatamente nell'interfaccia utente.

Al momento, JTextArea non mostra tutte le informazioni del registro fino a quando l'elaborazione non è stata completata dopo aver fatto clic sul pulsante. Come posso farlo rinfrescare in modo dinamico?

risposta

23

Ho riscontrato lo stesso problema con la mia applicazione. Ho avuto un pulsante "Esegui" la mia applicazione che ha eseguito alcune azioni e ha emesso i risultati su un JTextArea. Ho dovuto chiamare il metodo da una discussione. Ecco cosa ho fatto.

Ho diversi pulsanti di opzione che è possibile eseguire e quindi un pulsante "Esegui" per eseguire quell'azione particolare. Ho un'azione chiamata Convalida. Quindi quando controllo quel pulsante di opzione e clicco sul pulsante "Esegui", chiama il metodo validate(). Così ho messo questo metodo in una classe interna che ha implementato Runnable

class ValidateThread implements Runnable { 
    public void run() { 
     validate(); 
    } 
} 

Poi ho chiamato questa discussione nel ActionListener del pulsante "Esegui", come in modo

runButton.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent ae) { 
     // Some code checked on some radio buttons 
     if(radioButton.isSelected()) { 
      if(radioButton.getText().equals("VALIDATE")) { 
       Runnable runnable = new ValidateThread(); 
       Thread thread = new Thread(runnable); 
       thread.start(); 
      } 
     } 
    } 

}); 

Voila! L'output è ora inviato a JTextArea.

Ora, noterete che JTextArea non scorrerà verso il basso con il testo. Quindi è necessario impostare la posizione del cursore come

textArea.setCaretPosition(textArea.getText().length() - 1); 

Ora, quando i dati vengono aggiunti al JTextArea, sarà sempre scorrere verso il basso.

+3

Perché non utilizzare EventQueue.invokeLater (eseguibile)? –

+0

Non sono sicuro che fosse disponibile - il tuo commento è stato 4 anni dopo il mio lol – Ascalonian

0

Per questo è necessario il multithreading. Pronto a fare il grande passo?

+0

Ho il mio cappello duro. Quindi sì. – digiarnie

4

Come altri hanno già detto, questo richiede il multithreading. Dai uno sguardo a Concurrency in Swing.

Una soluzione sarebbe implementare l'elaborazione utilizzando SwingWorker. Il metodo doInBackground implementerebbe l'elaborazione e si invocerebbe il metodo di pubblicazione con la stringa da aggiungere come argomento. SwingWorker quindi sostituisce il metodo di processo per prendere un argomento String e aggiungerlo all'area di testo.

32

Prova questo:

jTextArea.update(jTextArea.getGraphics()); 
+0

è perfetto. Grazie :) – olyanren

+0

ha funzionato. Grazie :) –

+0

Funziona ed è molto facile da implementare. Questa dovrebbe essere la migliore risposta. – Nautilus

1

Mi dispiace per rispondere a questa domanda, che è stato pubblicato 4 anni fa, ma ho un'altra soluzione che ha funzionato per me. Ho appena usato i puntatori per aggiornare il JTextArea come tale:

//JScrollPane variable pane initialized with JTextArea area 
//We will update area with new text 
JTextArea temp = (JTextArea) pane.getViewPort().getView(); 
//new text to add 
JTextArea c = new JTextArea(); 
c.append("text \n)"; 
//update through pointers 
temp = c; 
pane.validate();