dcsimg
JScrollPane auto scrolling from a Thread does not work?
1 posts in topic
Flat View  Flat View
TOPIC ACTIONS:
 

Posted By:   Richard_Brochu
Posted On:   Thursday, June 19, 2003 04:59 AM

Text is appended to the displayArea using the text entered in the JTextField. If I append text to a JTextArea (in a JScrollPane) from a running Thread, the JScrollPane's autoscrolling does not work. The viewport remains at the top of the JScrollPane instead of scrolling to the newest entries. This works fine if not running with a Thread. What can be the problem and how can I get around this? Thank you in advance. To reproduce simply enter text in the textfield. The threaded application automatically retrieves the text from the text field. In the non-threaded application, the user must press . See code below (Non-Threaded application follows Threaded application). Threaded application: package documentev   More>>

Text is appended to the displayArea using the text entered in the JTextField. If I append text to a JTextArea (in a JScrollPane) from a running Thread, the JScrollPane's autoscrolling does not work. The viewport remains at the top of the JScrollPane instead of scrolling to the newest entries. This works fine if not running with a Thread. What can be the problem and how can I get around this? Thank you in advance.


To reproduce simply enter text in the textfield. The threaded application automatically retrieves the text from the text field. In the non-threaded application, the user must press . See code below (Non-Threaded application follows Threaded application).

Threaded application:

			
package documentevent;

/*
* Swing version
*/

import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;

public class DocumentEventThread extends JFrame {
JTextField textField = new JTextField(20);
JTextArea displayArea = new JTextArea(5, 20);

public DocumentEventThread() {
createFrame();
setVisible(true);

new Thread() {
public void run() {
while(!isInterrupted()) {
try {
Thread.sleep(3000);
}
catch(InterruptedException ie) {
break;
}

displayArea.append(textField.getText() + "
");
textField.setText("");
}
}
}.start();
}

public void createFrame() {
JButton button = new JButton("Clear");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
displayArea.setText("");
textField.requestFocus();
}
});

displayArea.setEditable(false);

getContentPane().add(textField, BorderLayout.NORTH);
getContentPane().add(new JScrollPane(displayArea), BorderLayout.CENTER);
getContentPane().add(button, BorderLayout.SOUTH);

pack();
}

public static void main(String[] args) {
DocumentEventThread def = new DocumentEventThread();
def.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
}
}



Non-Threaded application:
			

package documentevent;

/*
* Swing version
*/

import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;

public class DocumentEventFrame extends JFrame {
JTextField textField = new JTextField(20);
JTextArea displayArea = new JTextArea(5, 20);

public DocumentEventFrame() {
createFrame();
setVisible(true);
}

public void createFrame() {
JButton button = new JButton("Clear");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
displayArea.setText("");
textField.requestFocus();
}
});

textField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
displayArea.append(textField.getText() + "
");
}
});

displayArea.setEditable(false);

getContentPane().add(textField, BorderLayout.NORTH);
getContentPane().add(new JScrollPane(displayArea), BorderLayout.CENTER);
getContentPane().add(button, BorderLayout.SOUTH);

pack();
}

public static void main(String[] args) {
DocumentEventFrame def = new DocumentEventFrame();
def.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
}
}
   <<Less

Re: JScrollPane auto scrolling from a Thread does not work?

Posted By:   Ian_Warner  
Posted On:   Thursday, June 26, 2003 03:05 AM

What about SwingUtilities.invokeAndWait(Runnable) (synchronous call) or SwingUtilities.invokeLater(Runnable) (asynchronous call).



These methods cause Runnable.run() to be called from within the AWT event dispatching thread.



Your code sample modified:



//package documentevent;

/*
* Swing version
*/

import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;

public class DocumentEventThread extends JFrame {
JTextField textField = new JTextField(20);
JTextArea displayArea = new JTextArea(5, 20);

public DocumentEventThread() {
createFrame();
setVisible(true);

new Thread() {
public void run() {
while(!isInterrupted()) {
try {
Thread.sleep(3000);
}
catch(InterruptedException ie) {
break;
}

try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
displayArea.append(textField.getText() + "
");
textField.setText("");
}
});
}
catch (java.lang.reflect.InvocationTargetException ex) { }
catch (InterruptedException ex) {
return;
}
}
}
}.start();
}

public void createFrame() {
JButton button = new JButton("Clear");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
displayArea.setText("");
textField.requestFocus();
}
});

displayArea.setEditable(false);

getContentPane().add(textField, BorderLayout.NORTH);
getContentPane().add(new JScrollPane(displayArea), BorderLayout.CENTER);
getContentPane().add(button, BorderLayout.SOUTH);

pack();
}

public static void main(String[] args) {
DocumentEventThread def = new DocumentEventThread();
def.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
}
}

About | Sitemap | Contact