Extending JPanel changes JPanel behavior

All,

I am trying to center a JPanel in the middle of my JFrame. Below is the code I use to center the JPanel. What is confusing me is that when the panel in question, actionPnl, is declared as a JPanel, the centering code works beautifully. When I declare it as a CanvasPanel (see code below) it does not show up at all. Now, I thought that when you use 揈xtends?that the class you are creating inherits all attributes of the class you are extending however this behavior suggests otherwise. Am I overlooking some fundamental ingredient?

//private CanvasPanel actionPnl = new CanvasPanel();

private JPanel actionPnl =new JPanel();

private Box xp = Box.createHorizontalBox();

private Box yp = Box.createVerticalBox();

privatevoid center()

{

xp.add(Box.createHorizontalGlue());

xp.add(actionPnl);

xp.add(Box.createHorizontalGlue());

yp.add(Box.createVerticalGlue());

yp.add(xp);

yp.add(Box.createVerticalGlue());

}//end center()

publicclass CanvasPanelextends JPanel

{

private Image image;

public CanvasPanel()

{

setBackground (Color.WHITE);

setPreferredSize(new Dimension(600, 100));

}//end constructor CanvasPanel()

publicvoid paintComponent(Graphics g)

{

g.drawImage(image, 0, 0,null);

g.dispose();

}

publicvoid setImage(Image inImage)

{

image = inImage;

}

}

[2416 byte] By [Liam_Glancya] at [2007-10-2 10:07:03]
# 1

1) The code you posted isn't executable so I can't see the described behaviour.

2) You have changed functionality since you overrode the paintComponent(...) method. I doubt it would cause a problem but again I can't test your code.

3) You overrode the default size of the panel. Again this shouldn't cause a problem, but I can't test it.

4) Why are you using a panel to paint and Image. Just use a JLabel and add the ImageIcon to the JLabel.

camickra at 2007-7-13 1:24:18 > top of Java-index,Desktop,Core GUI APIs...
# 2

> 1) The code you posted isn't executable so I can't

> see the described behaviour.

I will try to set up something that is executable. This is part of a much larger program and posting all of the program is unrealistic.

>

> 4) Why are you using a panel to paint and Image. Just

> use a JLabel and add the ImageIcon to the JLabel.

What I am trying to acheive is to have two images, a cart and a pole, linked togeather so that when the cart moves left or right in response to arrow key input, the pole stays linked at its attachment point but changes its angle relative to the cart image. I did not think I could acheive this using JLabels. Then again I am a Java novice and this is one of the programs I decided to use to teach myself Java!

Thanks for the reply!

Liam_Glancya at 2007-7-13 1:24:18 > top of Java-index,Desktop,Core GUI APIs...
# 3

> This is part of a much larger program and posting all of the program is unrealistic.

We never want to see you entire program. We only want to see the code that demonstrates the incorrect behaviour.

> ....the pole stays linked at its attachment point but changes its angle relative to the cart image

So essentially you have code that controls where each image is painted on the panel. Well you can use a "null" LayoutManager which allows you to specify the exact location of a component. So you would just add the image the the label and postion the label on the panel. Read the Swing tutorial on [url http://java.sun.com/docs/books/tutorial/uiswing/layout/index.html]Using Layout Managers[/url] for a better description, and example, of Absolute Positioning.

camickra at 2007-7-13 1:24:18 > top of Java-index,Desktop,Core GUI APIs...
# 4

> We never want to see you entire program. We only want

> to see the code that demonstrates the incorrect

> behaviour

I pieced this together and it has the same behavior. It is what I would call "hack code" and does not follow good practices. But it gets the point across. Just toggle which actionPnl declaration to comment out to see the difference.

import java.awt.Color;

import java.awt.Dimension;

import java.awt.Graphics;

import java.awt.Image;

import javax.swing.JPanel;

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import java.awt.image.BufferedImage;

import java.awt.Graphics;

public class test extends JFrame

{

Container c;

boolean btnControl = false;

/******** toggle these two *********/

//private CanvasPanel actionPnl = new CanvasPanel();

private JPanel actionPnl = new JPanel();

/*************************************/

private Box xp = Box.createHorizontalBox();

private Box yp = Box.createVerticalBox();

public test()

{

//container

c = getContentPane();

c.setBackground(Color.BLACK);

c.setLayout(new BorderLayout());

//construction

buildActionPnl();

//add to JFrame

c.add(yp, BorderLayout.CENTER);

setSize(1200, 950);

setVisible(true);

}//end constructor balance()

private void buildActionPnl()

{

center();

}//end buildActionPnl()

private void center()

{

xp.add(Box.createHorizontalGlue());

xp.add(actionPnl);

xp.add(Box.createHorizontalGlue());

yp.add(Box.createVerticalGlue());

yp.add(xp);

yp.add(Box.createVerticalGlue());

}//end center()

public static void main(String args[])

{

test t = new test();

t.addWindowListener(

new WindowAdapter(){

public void windowClosing(WindowEvent we){

System.exit(0);

}

}

);

}

public class CanvasPanel extends JPanel

{

private Image image;

public CanvasPanel()

{

setBackground (Color.WHITE);

setPreferredSize(new Dimension(600, 100));

}//end constructor CanvasPanel()

public void paintComponent(Graphics g)

{

g.drawImage(image, 0, 0, null);

g.dispose();

}

}

}

I will research your suggested LayoutManager information and get back with how it works for me. At the moment I do not have code to control where each image is painted, that is what I am trying to take on.

Thanks for the help, it is appreciated!

Liam_Glancya at 2007-7-13 1:24:18 > top of Java-index,Desktop,Core GUI APIs...
# 5

> Just toggle which actionPnl declaration to comment out to see the difference.

Well actually it abends when I try to use the CanvasPanel. The image variable is null.

However, when I actually read in an image it paints as expected. The code is centered based on the preferredSize of the panel, not the size of the image. If you want the image to be centered, then you need to make the preferredSize of the panel equal to the size of the image.

Also, in an unrelated tip, if you want to close a window, instead of adding a WindowListner just use:

frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

camickra at 2007-7-13 1:24:18 > top of Java-index,Desktop,Core GUI APIs...
# 6

Sorry about the delay in replying. As this is a personal adventure, work and life often must take priority.

What I have done is use the JPanel approach and on your advice read up on Absolute Positioning. It was exactly what I needed. I was able to add key bindings between the two JLabels I am using and the left/right arrow keys and it all just came together, so a big thanks for the help!

I also changed the WindowListener to .setDefaultCloseOperation() and that worked great too! Is this prefered for performance, code optimization, or just a good java progamming practice?

Thanks again!

Liam_Glancya at 2007-7-13 1:24:18 > top of Java-index,Desktop,Core GUI APIs...