how to combine paintComponent with add(component)?  
Author Message
maestroff





PostPosted: 2003-10-29 2:40:00 Top

java-programmer, how to combine paintComponent with add(component)? I have a Java application with several classes that extend JPanels and
that, till now, didn't have any internal Swing components. They did
display text that was antialiased and sometimes animated by overriding
paintComponent in each of these custom classes. And this worked fine.

But now on one of the panels I want to add in the northeast corner
another customized JPanel extending object. When I just call
basePanel.add(newPan) the newPan would show up when first displayed
but then dissapear the next time repaint() is called on the basePanel.
I imagine I have to do something in the basePanel's paintComponent
method to make sure the new panel is repainted every time. But I'm not
sure how that is handled. Anyone have some advice? Maybe a quick
example?
 
maestroff





PostPosted: 2003-10-29 6:23:00 Top

java-programmer >> how to combine paintComponent with add(component)? A more acurate subject for this thread might have been "How do you
paint a JComponent on top of another JComponent?"
 
Babu Kalakrishnan





PostPosted: 2003-10-29 16:35:00 Top

java-programmer >> how to combine paintComponent with add(component)? Mike wrote:
> I have a Java application with several classes that extend JPanels and
> that, till now, didn't have any internal Swing components. They did
> display text that was antialiased and sometimes animated by overriding
> paintComponent in each of these custom classes. And this worked fine.
>
> But now on one of the panels I want to add in the northeast corner
> another customized JPanel extending object. When I just call
> basePanel.add(newPan) the newPan would show up when first displayed
> but then dissapear the next time repaint() is called on the basePanel.
> I imagine I have to do something in the basePanel's paintComponent
> method to make sure the new panel is repainted every time. But I'm not
> sure how that is handled. Anyone have some advice? Maybe a quick
> example?


Without seeing your code, it would be very difficult to guess why the
panel disappears the second time around. Normally the paint() method
of any JComponent will first call paintComponent on the component itself
and then call its paintChildren() method which causes all the children
added to the panel to get repainted (On top of the parent panel). So by
default you don't need to do anything specific in the paintComponent
method of the parent to paint the children. (All bets are off if you're
overriding the paint() method though)

You must be doing something in your code between your first repaint and
the second that either causes the child panel to get removed from its
parent (are you by any chance adding the same child to another container
?) or cause its size/location to change in such a manner that it isn't
visible on the screen. What LayoutManager do you use for the basePanel ?

BK

 
 
maestroff





PostPosted: 2003-10-30 0:05:00 Top

java-programmer >> how to combine paintComponent with add(component)? I figured out what I was doing wrong. In my overloaded paintComponent
method I started with super.paintComponent(g). What I was missing, and
what fixed it when I put it in was calling super.paintChildren(g) on
the next line. Thanks BK.


Babu Kalakrishnan <email***@***.com> wrote in message news:<bnnu44$13k22a$email***@***.com>...
>
> Without seeing your code, it would be very difficult to guess why the
> panel disappears the second time around. Normally the paint() method
> of any JComponent will first call paintComponent on the component itself
> and then call its paintChildren() method which causes all the children
> added to the panel to get repainted (On top of the parent panel). So by
> default you don't need to do anything specific in the paintComponent
> method of the parent to paint the children. (All bets are off if you're
> overriding the paint() method though)
>
> You must be doing something in your code between your first repaint and
> the second that either causes the child panel to get removed from its
> parent (are you by any chance adding the same child to another container
> ?) or cause its size/location to change in such a manner that it isn't
> visible on the screen. What LayoutManager do you use for the basePanel ?
>
> BK
 
 
Babu Kalakrishnan





PostPosted: 2003-10-30 1:03:00 Top

java-programmer >> how to combine paintComponent with add(component)? Mike wrote:
> I figured out what I was doing wrong. In my overloaded paintComponent
> method I started with super.paintComponent(g). What I was missing, and
> what fixed it when I put it in was calling super.paintChildren(g) on
> the next line. Thanks BK.
>

That doesn't look quite right either. Are you by any chance overriding
the paint() method as well ? If so try to avoid that. It is the paint
method of a JComponent that calls paintcomponent followed by
paintChildren. So overriding just the paintComponent method shouldn't
have interfered with the paintChildren call.

BK

 
 
maestroff





PostPosted: 2003-10-30 23:23:00 Top

java-programmer >> how to combine paintComponent with add(component)? No, I'm only overriding paintComponent. Atleast in the base Panel.
However I am getting some odd error messages since I made the latest
change. What makes them odd is that everything visualy seems to be
working. But I'm getting an error message anyway. Let me explain some
more...

The JPanel (lets call it panA) that I add onto the base JPanel (panB)
is initialized with a CardLayout. Into panA I then put two more JPanel
extending objects as cards. One called ImagePanel for displaying
images, and the other called VideoPanel which uses the JMF api to
display video clips. Don't worry about the video one though, as I only
get the error msgs when the ImagePanel is the active card.

Here is the basic ImagePanel code:

public class ImagePanel extends JPanel
{
private ImageIcon image = null;

/**
* Construct without initializing media player
*/
public ImagePanel(String picture)
{
this();
setImage(picture);
}

public ImagePanel()
{
setOpaque(false);
}

// I also tried this as paint(g) but it didn't make any difference
public void paintComponent(Graphics g)
{
if (! g.drawImage(image.getImage(), 0, 0,
image.getImageObserver()))
System.out.println("Warning: ImagePanel image draw failed");
}

private void setImage(String picture)
{
image = new ImageIcon(picture);
setPreferredSize(new Dimension(image.getIconWidth(),
image.getIconHeight()));

// Use layout manager to set minimum height and width
setLayout(new FlowLayout(FlowLayout.CENTER,
image.getIconWidth() / 2,
image.getIconHeight() / 2));
}

public void changeImage(String picture)
{
setImage(picture);
repaint();
}
}

The problem is that I keep seeing that "Warning: ImagePanel image draw
failed" message even though the pictures are displayed when they
should be, don't dissapear, and change when they should. I do use
another instance of this class in another place in my application and
there it works fine too, but without the complaints. What could cause
the draw to think it failed, and yet still have the image be present
on the screen?? Its very confusing.

And in case it helps you understand my earlier issue, here is a
simplified version of the relevant parts of "panB":

public class BasePanel extends JPanel
{
public BasePanel(Config cfg)
{
...

setOpaque(false);
setLayout(null);

mediaPanel = new JPanel(mediaCards = new CardLayout());
mediaPanel.setOpaque(false);

// Will be made visible later by a call from a separate thread
mediaPanel.setVisible(false);

videoPanel = new VideoPanel();
picturePanel = new ImagePanel();

mediaPanel.add(picturePanel, IMAGE_MEDIA_CARD);
mediaPanel.add(videoPanel, VIDEO_MEDIA_CARD);

add(mediaPanel);
mediaPanel.setBounds(cfg.getWindowResolution().width - 340, 0,
340, 260);
}

public void paintComponent(Graphics g)
{
super.paintComponent(g);
super.paintChildren(g);

if (booleanVariable)
{
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);

g2.setColor(answerColor);
g2.setFont(textFont);

....
// call g2.drawString(....); many times
....

g2.dispose();
}
}
}


>
> That doesn't look quite right either. Are you by any chance overriding
> the paint() method as well ? If so try to avoid that. It is the paint
> method of a JComponent that calls paintcomponent followed by
> paintChildren. So overriding just the paintComponent method shouldn't
> have interfered with the paintChildren call.
>
> BK
 
 
maestroff





PostPosted: 2003-10-31 3:48:00 Top

java-programmer >> how to combine paintComponent with add(component)? Figured it out myself. You were right. I didn't need paintChildren().
The cause both of the initial disapearences and of those error
messages was my calling g2.dispose() at the end of the paintComponent
method. That apparently prevented the child component from painting.
The picture would still appear if I used super.paintChildren(g)
because it would try it twice on each repaint, and it would only fail
(and give the error message) the second time. I used g2.dispose()
because it seemed to be the standard thing to do at the end of a paint
overload. Sort of like always closing a DB connection after a JDBC
process. Using it is supposedly more efficient. Is there a better
place to call dispose, or should I just drop it completely?
 
 
Babu Kalakrishnan





PostPosted: 2003-11-1 0:55:00 Top

java-programmer >> how to combine paintComponent with add(component)? Mike wrote:
> Figured it out myself. You were right. I didn't need paintChildren().
> The cause both of the initial disapearences and of those error
> messages was my calling g2.dispose() at the end of the paintComponent
> method. That apparently prevented the child component from painting.
> The picture would still appear if I used super.paintChildren(g)
> because it would try it twice on each repaint, and it would only fail
> (and give the error message) the second time. I used g2.dispose()
> because it seemed to be the standard thing to do at the end of a paint
> overload. Sort of like always closing a DB connection after a JDBC
> process. Using it is supposedly more efficient. Is there a better
> place to call dispose, or should I just drop it completely?

Drop it altogether. You should only dispose off recources that you
allocated yourself. So if you created a Graphics object from say a
BufferedImage, it is your responsibility yo dispose it off.

The Graphics object passed to you as an argument to the paint method is
something which the AWT (or Swing) painting subsystem created, and it
will perform the disposal when it is done with it.

BK