2009-03-10 7 views
23

Estoy tratando de crear una interfaz de usuario Swing muy simple que registra información en la pantalla a través de un JTextArea ya que el procesamiento se realiza en segundo plano. Cuando el usuario hace clic en un botón, quiero que cada llamada a:¿Actualizas dinámicamente JTextArea cuando se produce el procesamiento?

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

para que aparezca inmediatamente en la interfaz de usuario.

Por el momento, JTextArea no muestra toda la información de registro hasta que el proceso se haya completado después de hacer clic en el botón. ¿Cómo puedo hacer que se actualice de forma dinámica?

Respuesta

23

Me encontré con el mismo problema con mi aplicación. Tenía un botón "Ejecutar" mi aplicación que realizaba algunas acciones y sacaba los resultados a un JTextArea. Tuve que llamar al método desde un hilo. Aquí esta lo que hice.

Tengo varios botones de opción que se pueden hacer, y luego un botón "Ejecutar" para ejecutar esa acción en particular. Tengo una acción llamada Validate. Entonces cuando verifico ese botón de radio y hago clic en el botón "Ejecutar", llama al método validate(). Así que primero puesto este método en una clase interna que implementa Ejecutable

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

luego me llamó a este hilo en el ActionListener del botón "Ejecutar", como así

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! La salida ahora se envía a JTextArea.

Ahora, notará que JTextArea no se desplazará hacia abajo con el texto. Así que hay que ajustar la posición de intercalación como

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

Ahora, cuando los datos se añaden a la JTextArea, siempre se desplazará hacia abajo.

+3

¿Por qué no utilizar EventQueue.invokeLater (ejecutable)? –

+0

No estoy seguro de que estuviera disponible - su comentario fue 4 años después de que mi lol – Ascalonian

0

Necesitarás multihilo para esto. ¿Listo para dar el paso?

+0

Tengo mi casco puesto. Entonces sí. – digiarnie

4

Como han dicho otros, esto requiere multithreading. Eche un vistazo al Concurrency in Swing.

Una solución sería implementar el procesamiento utilizando un SwingWorker. El método doInBackground implementaría el procesamiento e invocaría el método de publicación con la cadena que se adjuntará como argumento. Su SwingWorker anularía el método de proceso para tomar un argumento de Cadena y anexarlo al área de texto.

32

Prueba esto:

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

es perfecto. Gracias :) – olyanren

+0

funcionó. Gracias :) –

+0

Funciona y es muy fácil de implementar. Esa debería ser la mejor respuesta. – Nautilus

1

lo siento por responder a esta pregunta que fue publicada hace 4 años, pero no tengo otra solución que funcionó para mí. Acabo de utilizar punteros para actualizar el JTextArea como tal:

//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(); 
Cuestiones relacionadas