This week's book giveaway is in the Servlets forum.
We're giving away four copies of Murach's Java Servlets and JSP and have Joel Murach on-line!
See this thread for details.
The moose likes Swing / AWT / SWT and the fly likes Only repaints once Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "Only repaints once" Watch "Only repaints once" New topic
Author

Only repaints once

Chris Crawford
Ranch Hand

Joined: Jun 22, 2011
Posts: 85

I've been struggling with Swing for years now and have NEVER gotten the hang of it, although I have been able to get quite a lot done. I always use a system of nested BoxLayouts, as this almost always allows me to get the layout I want. I have been successful with lots of different Components. Usually I figure things out by trying endless variations until something actually works. But this time I'm truly bamboozled.

I have a complicated JFrame containing lots of different Components. It all works quite well; I can change the contents of different Components and everything is hunky-dory. BUT now I have added something that really screws up. I have a JButton called historyButton that switches the contents of one JPanel between two alternatives. Here's its ActionListener:



The intent of this code, then, is to permit the user to click on the "History" JButton and see one part of the JFrame change its contents. The label of the "History" JButton will also change to read "Main". When the user clicks on that JButton a second time, the contents should change back to their original imagery.

The Method composeMainDisplay() lays out those Components of the JFrame that are in any manner variable. That is to say, some portions of the JFrame are constant, and are set up once at program initialization. Other components can change, and they are all set up in the Method composeMainDisplay(). One of those variable components is leftPanel. Depending on the value of displayType, it will have either 1) a JLabel containing an ImageIcon or 2) a JPanel containing a bar graph. It has other stuff as well; the variable Component is added to leftPanel at the appropriate time necessary to obtain the correct ordering of the Components. Here's the relevant code snippet from inside composeMainDisplay():



Here's the problem: when running the program, clicking on the "History" JButton once will correctly bring up the bar graph. Clicking again on that same JButton (now relabeled "Main") a second time does NOT, however, replace the bar graph JPanel with the required JLabel. Indeed, all further clicks on that JButton have no effect on the display. The diagnostic messages "displaying imageLabel" and "displaying newHistory" appear as they should, so the code is executing properly. It's just that nothing is showing up on the screen!

There are all sorts of weird variations on this. For example, suppose I comment out the two Java lines above that set the text of the JButton. Then it gets even more magical: nothing happens at all! Indeed, all the other JButtons in that JFrame stop responding. I have diagnostic lines inserted in the code that notify me when particular chunks of code are executed, and the ActionListener for all those dead buttons is never called! It's as if the program is locked up -- except that ONE button will break the lock -- and I have no idea why that particular button has that effect.

I've been spitting out diagnostics, trying all sorts of random variations, and nothing makes sense. Yet, except for this one problem with swapping JPanel contents, the display works perfectly.

As you can see, this is a truly messy problem, and I doubt that anybody will be able to fix it for me, but I'm wondering if anybody could suggest a debugging strategy that at least would get me on the right path.
Alexander Kober
Ranch Hand

Joined: Aug 05, 2011
Posts: 32

Hope you don't take offense to me asking what might be a dumb question, but does your composeMainDisplay method properly revalidate leftPanel? The issues you're describing do sound a lot like you might have missed that method call...
Chris Crawford
Ranch Hand

Joined: Jun 22, 2011
Posts: 85

Yes, I've been sprinkling calls to update() around like holy water, to no effect. I've also tried ubiquitous calls to validate() and invalidate() (at different times, of course). However, I managed to stumble upon what I think is the solution: repaint(). Somewhere I had read that paint() and repaint() are low-level calls and should be avoided; update() and validate() are the proper calls to make to force an application-level repainting. But while searching the Internet for details on the exact process by which Swing renders a window, I came across a reference mentioning that repaint() could be used, but not paint(). So I tried repaint() and the damn think worked -- I nearly fell out of my chair. I still haven't verified that it works in all conditions, but so far it's looking good.

But thanks for the help anyway!
Rob Camick
Ranch Hand

Joined: Jun 13, 2009
Posts: 2152
    
    7
Yes, I've been sprinkling calls to update() around like holy water, to no effect. I've also tried ubiquitous calls to validate() and invalidate()


Maybe it wasn't clear but Alexander asked if you use revalidate()?

You should never use update().

In an AWT application you might use invalidate() and validate().

In Swing the general rule is:



If you are removing all the components from a panel and replacing them when new components then you should be using a CardLayout. See How to Use Card Layout. Then the CardLayout will worry about all the above code.
Chris Crawford
Ranch Hand

Joined: Jun 22, 2011
Posts: 85

revalidate()? I was completely unaware of that method until now. I haven't seen it used in any of the sample code I've learned from. Is there also a supervalidate(), semivalidate(), retrovalidate(), or subvalidate()?

Is the difference between revalidate() and repaint() that revalidate() results in the repainting of only the altered portions of the image?

I had looked at CardLayout but was scared away by its initial warning about writing layout code.
Darryl Burke
Bartender

Joined: May 03, 2008
Posts: 4523
    
    5

Chris Crawford wrote:revalidate()? I was completely unaware of that method until now. I haven't seen it used in any of the sample code I've learned from.

Been learning from old outdated AWT learning resources, have you?

Chris Crawford wrote:Is there also a supervalidate(), semivalidate(), retrovalidate(), or subvalidate()?

Reading the API will answer that.

Chris Crawford wrote:Is the difference between revalidate() and repaint() that revalidate() results in the repainting of only the altered portions of the image?

Reading the API will answer that too.

Chris Crawford wrote:I had looked at CardLayout but was scared away by its initial warning about writing layout code.

What warning?

luck, db
There are no new questions, but there may be new answers.
Chris Crawford
Ranch Hand

Joined: Jun 22, 2011
Posts: 85

Darryl Burke wrote:
Been learning from old outdated AWT learning resources, have you?

Mostly from the Java2 Overview, but it's not strong on the teaching aspect, not even the "How to Use" pages.

Darryl Burke wrote:
Chris Crawford wrote:I had looked at CardLayout but was scared away by its initial warning about writing layout code.

What warning?

This one at the top of the page How to Use CardLayout

Note: This lesson covers writing layout code by hand, which can be challenging. If you are not interested in learning all the details of layout management, you might prefer to use the GroupLayout layout manager combined with a builder tool to lay out your GUI. One such builder tool is the NetBeans IDE. Otherwise, if you want to code by hand and do not want to use GroupLayout, then GridBagLayout is recommended as the next most flexible and powerful layout manager.
Rob Camick
Ranch Hand

Joined: Jun 13, 2009
Posts: 2152
    
    7
This one at the top of the page How to Use CardLayout


That same comment is there for all the other layout managers (FlowLayout, BoxLayout, BorderLayout...). Yet to choose to do your own layout using these layout managers anyway.

So why do you consider a CardLayout more difficult than a FlowLayout?

Read the whole tutorial and play with the examples.
Chris Crawford
Ranch Hand

Joined: Jun 22, 2011
Posts: 85

I dunno, I found BoxLayout to be pretty simple and straightforward, whereas CardLayout seems more complicated. I'm really trying to obey the KISS principle.
Rob Camick
Ranch Hand

Joined: Jun 13, 2009
Posts: 2152
    
    7
whereas CardLayout seems more complicated.


What about the example code from the tutorial do you find complicated?

I'm really trying to obey the KISS principle.


And that is the purpose of using a CardLayout. It is only used when you want to swap components on a panel. Instead of swapping comopnents you create two panels and swap the panels.
Chris Crawford
Ranch Hand

Joined: Jun 22, 2011
Posts: 85

And that is the purpose of using a CardLayout. It is only used when you want to swap components on a panel. Instead of swapping comopnents you create two panels and swap the panels.


Ah so! I had not checked CardLayout recently; when I looked at it (most recently, some months ago), I saw no need for its complexity, and resolved to do everything with BoxLayout. But I will definitely convert over to CardLayout. Thanks much!
Rob Camick
Ranch Hand

Joined: Jun 13, 2009
Posts: 2152
    
    7
Ah so! I had not checked CardLayout recently;


What do you mean recently?

You where asked to read the tutorial, download the examples and test the examples.

So you are telling me I wasted my time helping because you didn't even bother to test the example code from the tutorial?

Chris Crawford
Ranch Hand

Joined: Jun 22, 2011
Posts: 85

Rob, calm down; you simply failed to notice that my comment was in past perfect tense. Yes, I have read all of that stuff now. But I didn't read it before you pointed it out to me; only the initial stuff on CardLayout, and that was months ago. Thanks again for your help.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Only repaints once
 
Similar Threads
JFrame and JPanel
Why aren't my components wrapping?
Problems loading image into a JLabel located in a JScrollPane
Problems adding two panels
no such method error