Forçar scroll da JTextArea

Alguém sabe como forçar o scroll da JTextBox a descer conforme ela JTextBox vai sendo dinamicamente preenchida?

Eu tenho uma JTextBox, mas conforme vou preenchendo o scroll fica lá em cima, e o texto vai indo lá pra baixo…
preciso que ele desca junto.

[]´s!

Você quer dizer JTextArea?

this.textArea.append("guj");

Sim, JTextArea, isso msm, desculpe a falha.

Mas não entendi como isso pode forçar o scroll a descer, o append não seria para acrescentar um texto á textarea?

[]´s!

Isso!
Tu nao está acrescentando texto e quer que o scroll acompanhe?

Olha esse exemplo, que gera de tempos em tempos uma string aleatória.

public class AutoScroll extends JPanel implements ActionListener {

	private JTextArea textArea;
	private Random random = new Random(Calendar.getInstance().getTimeInMillis());

	public AutoScroll() {
		this.initialize();
		this.initThread();
	}

	protected void initialize() {
		this.setLayout(new BorderLayout());
		this.textArea = new JTextArea();
		this.add(new JScrollPane(this.textArea), BorderLayout.CENTER);
	}

	public void initThread() {
		Timer t = new Timer(600, this);
		t.start();
	}

	public void actionPerformed(ActionEvent e) {
		byte[] b = new byte[this.random.nextInt(20)];
		this.random.nextBytes(b);

		this.textArea.append(new String(b) + "\n");
	}

	public static void main(String[] args) {
		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		AutoScroll auto = new AutoScroll();
		frame.setContentPane(auto);
		frame.setSize(300, 200);
		frame.setVisible(true);
	}
}

[code] public minhaClasse() {

                            JPanel p1 = new JPanel();
	JTextArea texto = new JTextArea(20, 20);
	
	texto.setLineWrap(true);
	texto.setWrapStyleWord(true);
	texto.setFont(new Font("Serif", Font.ITALIC, 14));

	JScrollPane barra = new JScrollPane(texto); //Adiciona Scroll no TextArea
	barra.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
	
	p1.add(barra); //Adiciona a Scroll ao painel
	
}[/code]

[quote=fabiofalci]Isso!
Tu nao está acrescentando texto e quer que o scroll acompanhe?

[/code][/quote]
Kra, estranho, o append tb não está fazendo o scroll descer…
Vc está usando java 6?

[]´s

Kra, pois é, não sei o q está acontecendo, mas dá um erro…não sei se é pq eu mando a thread adormecer…
Os objetivos são dois: fazer o primeito botão chamar o método, e preencher a jTextarea da classe MainGui pela classe Tarefa.

Porém, nenhum dos dois acontece:

Classe da GUI:

package testsPack;

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class MainGui extends javax.swing.JFrame 
{		
	private static final long serialVersionUID = 1L;

	private static javax.swing.JButton jButton1, jButton2, jButton3;
	private static javax.swing.JScrollPane jScrollPane1;
	private static javax.swing.JScrollPane jScrollPane2;
	public static javax.swing.JTable jTable1;
	public static javax.swing.JTextArea jTextArea1;

	public MainGui() 
	{		
		initComponents();			
	}	    
	
	public static void main(String args[]) 
	{	    	
		java.awt.EventQueue.invokeLater(new Runnable() 
		{
			public void run() 
			{
				new MainGui().setVisible(true);
			}
		});
	}
		
	private void initComponents() 
	{	
		setTitle("WebService Consulta");
		setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

		jButton1 = new javax.swing.JButton();
		jButton1.setText("_Start_");	
		jButton1.addActionListener
		(
			new ActionListener()
			{		    
				public void actionPerformed(ActionEvent e1)
				{
					TarefaContinua.start();	
				}
			}
		);

		jButton2 = new javax.swing.JButton();
		jButton2.setText("_Stop_");
		jButton2.addActionListener
		(
			new ActionListener()
			{		    
				public void actionPerformed(ActionEvent e2)
				{
			    	TarefaContinua.stop();	
			    }
			}
		);	  

		jButton3 = new javax.swing.JButton();
		jButton3.setText("_Logs_");
		jButton3.addActionListener
		(
			new ActionListener()
			{		    
				public void actionPerformed(ActionEvent e3)
				{
					TarefaContinua.exit();	
				}
			}
		);	

		jScrollPane1 = new javax.swing.JScrollPane();
		jScrollPane2 = new javax.swing.JScrollPane();

		jTextArea1 = new javax.swing.JTextArea();
		jTextArea1.setColumns(20);
		jTextArea1.setRows(5);		
		jTextArea1.setEditable(false);
		jTextArea1.setBackground(Color.BLACK);
		jTextArea1.setDisabledTextColor(Color.ORANGE);		
		jTextArea1.setEnabled(false);		
				
		jScrollPane1.setViewportView(jTextArea1);	
			
		jTable1 = new javax.swing.JTable();
		jTable1.setEnabled(false);
		jTable1.setModel(new javax.swing.table.DefaultTableModel
		(
				new Object[][] 
				{ 
					{1, 111}, {2, 222}, {3, 333}, 
					{4, 444}, {5, 555}, {6, 666}
				},
				new String [] 
				{
					"Status", "Total"
				}
		)
	);
		jScrollPane2.setViewportView(jTable1);

//INICIO NAO SE PREOCUPE COM ISSO E APENAS O POSICIONAMENTO DOS 
//COMPONENTES GERADO AUTOMATICAMENTE PELO NETBEANS

		org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
		getContentPane().setLayout(layout);
		layout.setHorizontalGroup(
				layout.createParallelGroup(org.jdesktop.layout.GroupLayout.CENTER)
				.add(layout.createSequentialGroup()
						.addContainerGap()
						.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.CENTER)
								.add(layout.createSequentialGroup()
										.add(jScrollPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 460, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
										.addContainerGap())
										.add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
												.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
												.add(jScrollPane2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 375, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
												.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
												.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
														.add(jButton3)
														.add(jButton2)
														.add(jButton1))
														.add(31, 31, 31))))
		);
		layout.setVerticalGroup(
				layout.createParallelGroup(org.jdesktop.layout.GroupLayout.CENTER)
				.add(layout.createSequentialGroup()
						.add(19, 19, 19)
						.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
								.add(layout.createSequentialGroup()
										.add(jButton1)
										.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
										.add(jButton2)
										.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
										.add(jButton3))
										.add(jScrollPane2, 0, 0, Short.MAX_VALUE))
										.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
										.add(jScrollPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 300, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
										.add(15, 15, 15))
		);
		pack();		

//FIM NAO SE PREOCUPE COM ISSO E APENAS O POSICIONAMENTO DOS 
//COMPONENTES GERADO AUTOMATICAMENTE PELO NETBEANS
	}	
}

Classe da tarefa:

package testsPack;

import java.text.SimpleDateFormat;
import java.util.Date;

public class TarefaContinua
{	
	private static final long INTERVALO = 3600000;
	private static int CICLO = 1;	
	private static Thread t = new Thread();
	static MainGui mg = new MainGui();
			
	public static void start()
	{		
		try		
		{				
			SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy - hh:mm:ss");	
			
			t.start();			
			MainGui.jTextArea1.append("\nPROCESSO INICIADO...\n");
			
			Date d1 = new Date();
			mg.jTextArea1.append("INICIO: " + sdf.format(d1));		
								
			mg.jTextArea1.append("------------TAREFAAAAAAA------------");

			Date d2 = new Date();
			mg.jTextArea1.append("FIM: " + sdf.format(d2));					
										
			t.sleep(INTERVALO); //milisegundos 
			start();
		}
		catch(Exception e)
		{			
			e.printStackTrace();
		}
	}	
	
	public static void stop() {
		mg.jTextArea1.append("STOP");
		t = null;
	}	    		
	public static void exit() {		
		mg.jTextArea1.append("BYE BYE");
		System.exit(0);		
	}
}

Quando clico no Start ele congela junto com a Thread, e depois dá o seguinte erro:

Agradeço qq ajuda pessoal, abraços!

Olá amigo!

Não sei se entendi direito, eu tenho um JList que fica dentro de um JScrollPane e tive o mesmo problema que vc. No meu caso, para resolver, criei o método abaixo. Claro que está configurado com os tamanhos para o meu caso. Veja se funciona se algo parecido consegue te ajudar:

OBS: É um JList dentro de um JScrollPane, configurado pra que apareça 8 itens antes de começar a rolagem da barra.

[code]/**

  • Verifico se na lista foi excedido o número de itens que cabem na tela (8 itens). Se isso ocorrer,

  • faço a rolagem da barra de rolagem vertical do scroll pane que a lista está dentro.

  • @param lista Lista em questão

  • @param tamanhoArray Quantidade de elementos no array da lista

  • @param posicao Posição que deverá ser apresentada depois da rolagem da barra
    */
    public void rolarBarraLista(JList lista, int tamanhoArray, int posicao){

    // se tiver até 8 itens, não preciso fazer nada
    if (tamanhoArray <= 8)
    return;

    JScrollPane scroll = (JScrollPane)lista.getParent().getParent();

    // altura que cada label ocupa dentro da lista (incluindo seu espaço entre um e outro):
    // altura do scroll dividido pela quantidade de labels que aparecem no viewport
    int alturaLabel = scroll.getHeight() / 8; // medida de espaço que cada label ocupa no scroll (incluindo o espaco entre eles)

    // posição onde o viewport do scroll deve ficar: a altura dos labels + espaço entre eles, multiplicado
    // pela quantia de labels que já tem na lista (menos o label atual) + a altura entre o último label e
    // o label atual
    int posY = alturaLabel * posicao;

    // crio o novo ponto que será o X já existente e o novo Y calculado
    Point p = new Point((int) scroll.getViewport().getViewPosition().getX(), posY);

    // aplico o ponto ao scroll
    scroll.getViewport().setViewPosition§;
    scroll.validate();
    }[/code]

Dê uma olhada no ViewPort do JScrollPane…Você pode setar o recorte (o retângulo) que deseja ver do que está dentro do scroll setando alguns parâmetros da viewport…

Vale a pena ressucitar .
Pesquisando sobre o assunto encontrei uma solução mais elegante.
Modificando o caret ( caret é o ponto de entrada do textarea , algo como o cursor ).

jTextArea.append(“texto”);
jTextArea.setCaretPosition(jTextArea.getText().length());

Funciona perfeitamente.

v_vinicius_v, a sua resposta está correta, funcionou sim, levou a scroll bar para o final do textArea, mas encontrei uma dificuldade quanto a sua velocidade, pois printei muitas coisas juntas no mesmo textArea e ele travou bastante!

Pessoal, soluções para isso?

Obrigado.