Get the tools you need to learn Java skills fast!
Video tutorials, eBooks, hands-on lab exercises, sample code.
Get started
The moose likes Swing / AWT / SWT and the fly likes weird glitch in Swing GUI Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login

Win a copy of Badass: Making Users Awesome this week in the Game Development forum!
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "weird glitch in Swing GUI" Watch "weird glitch in Swing GUI" New topic

weird glitch in Swing GUI

Jon Dornback
Ranch Hand

Joined: Apr 24, 2002
Posts: 137
I have a JFrame with several components in a border layout: some JButtons in the west, a JPane in center, and a JTextArea inside of a JScrollPane in the south. when a button is clicked, a new thread is started to draw things in the center JPane.
while the thread is running, an ActionListener detects certain events and adds a message to the JTextArea. here's the glitch: sometimes when a message is added, part of the JTextArea is drawn over another component! I've seen buttons replaced by messages, and the JPane partially overwritten by a copy of the JTextArea. It only happens intermittently and apparently randomly. The next time the window is redrawn (another button clicked, window resized, etc) everything is back to normal.
I'm not exactly sure why this is happening, but i know it has to do with the messages being added event-wise while the thread is running. if I don't use the ActionListener and add messages to the JTextArea directly with the append() method (or not at all), everything works fine.
Has anyone else experienced something similar to this? If so, how do I prevent it? I have only tested this on one machine, so i'm not sure if it is specific to this set up or not. I am not sure how to go about solving it since there's no good way of controlling the GUI thread. Any suggestions?
machine set up:
amd athlon 1700+
pny geforce2 32mb graphics card
windows2000 server
java sdk 1.4.1_01

use the [CODE] tags - it makes it much easier for people to help you.
Jon Dornback
Ranch Hand

Joined: Apr 24, 2002
Posts: 137
after much debugging, I have tracked the problem down to the JScrollPane. I'm not exactly sure why Java/Swing is behaving like this, but I found the cause:
while the thread that controls the drawing on the JPanel is running, an event is generated that sends a message. In my event handler, the message is appended to the JTextArea, and then the JScrollPane is adjusted so that the scroll pane is at the bottom and the user can see the last message that was appended. I do this using the following:
where outputPane is the JScrollPane that holds the JTextArea. If i remove this functionality, the messages are appended, and there are no problems (but the scroll pane isn't adjusted). I tried synchronizing on the scroll pane, the scroll bar, the BoundedRangeModel of the scroll bar, and the text area to no avail. I tried moving the scroll bar adjustment in to the drawing thread, in to the action listener that initiates the thread with no better luck.
the only thing I can imagine that is happening is that somehow while Java is switching between the GUI thread, program thread, and drawing thread, it sometimes executes the getMaximum() method, then for some unfathomable reason still has part of the JTextArea in memory to be drawn when it goes to update another component, and that component is drawn with the contents of the text area. is this worthy of reporting to Sun, a "known issue", or a swing "feature"? I haven't yet checked the bug database.
my best solution so far is to not automatically scroll the pane. it's a poor work-around, but i'm currently stumped. anybody got any ideas?
Dionysios Zagreus

Joined: Jul 08, 2003
Posts: 2
This is a Swing multithread issue.
Try having your ActionListener call SwingUtilities.invokeLater(Runnable) to update your JTextArea.
First, create an appropriate Runnable object, as follows:
Runnable oTextUpdate = new Runnable() {
public void run() {
// insert code to update JTextArea here
Then invoke it like this:
Hope this helps.
Jon Dornback
Ranch Hand

Joined: Apr 24, 2002
Posts: 137
that was precisely it. i read the sun tutorials that said the same thing. I updated the code so that the scroll pane is adjusted in a thread that is handed over to the invokeLater method, and it seems to have cured the problem.
thanks for the help and pointing me in the right direction.
I agree. Here's the link:
subject: weird glitch in Swing GUI