wood burning stoves 2.0*
The moose likes Applets and the fly likes Why does getSize() need to be inside Canvas's paint method? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCM Java EE 6 Enterprise Architect Exam Guide this week in the OCMJEA forum!
JavaRanch » Java Forums » Java » Applets
Bookmark "Why does getSize() need to be inside Canvas Watch "Why does getSize() need to be inside Canvas New topic
Author

Why does getSize() need to be inside Canvas's paint method?

Jamie Cole
Ranch Hand

Joined: Feb 03, 2000
Posts: 36
I tried to use getSize.width() and getSize.height() to scale a graph I was drawing in a canvas. I eventually discovered that both were yielding values of zero when used at the top of the canvas subclass, which of course, made my graph scale down to an invisible nothing. Once I moved the getSize()s into my paint method, they found the proper dimensions of the canvas, and everything worked fine. My question: Do the getSize() methods always need to be in paint() to find the size of the component in which they're called? Why don't they find the size of the canvas no matter where in the canvas class they are placed?
Here's the whole program in the form in which it did not work. Moving the getSize() calls down into paint made it work. (You'd need the much larger Expr.class to actually run this file, and I'll post the Expr.java if needed, which I doubt.)
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class FunctionGrapher3 extends Applet
{
TextField bottom;
Label top;
FunctGraphCanvas canvas;
public void init()
{
setLayout( new BorderLayout(2,2) );
setBackground(Color.gray);
bottom = new TextField();
bottom.setBackground(Color.white);
bottom.setEditable(true);
top = new Label("Enter a function and press return.");
top.setBackground(Color.white);
canvas = new FunctGraphCanvas();
add(bottom, BorderLayout.SOUTH);
add(top, BorderLayout.NORTH);
add(canvas);
}
public Insets getInsets()
{
return new Insets(5, 5, 5, 5);
}
class FunctGraphCanvas extends Canvas implements ActionListener
{
double[] xarray = new double[300];
double[] yarray = new double[300];
Expr fofx;
int width = getSize().width;
int height = getSize().height;
FunctGraphCanvas()
{
setBackground(Color.yellow);
bottom.addActionListener(this);
fofx = null;
}
public void actionPerformed(ActionEvent evt)
{
top.setText("Processing . . .");
setData();
repaint();
}
public void setData()
{
double x = -5.0;
double increment = 1.0/30.0;
for (int i = 0; i < 300; i++)
{
xarray[i] = x;
x += increment;
}
String userf = bottom.getText();
try
{
for (int i = 0; i < 300; i++)
{
fofx = new Expr( userf );
yarray[i] = fofx.value( xarray[i] );
top.setText(xarray[i] + " " + yarray[i]);
}
}
catch (IllegalArgumentException e)
{
top.setText("Invalid Expression" + e.getMessage() );
}
}
public void paint(Graphics g)
{
g.setColor(Color.blue);
if (fofx == null)
{
g.drawString("No function available.", 20, 20);
}
else
{
g.drawString("y = " + fofx.getDefinition(), 20, 20);
g.drawLine( width/2, 5, width/2, height-5 );
g.drawLine( 5, height/2, width-5, height/2 );
for (int i = 0; i < 299; i++)
{
int a = (int)( (xarray[i] + 5)/10 * width );
int b = (int)( (5 - yarray[i])/10 * height );
int c = (int)( (xarray[i + 1] + 5)/10 * width );
int d = (int)( (5 - yarray[i + 1])/10 * height );
g.setColor(Color.red);
g.drawLine( a, b, c, d );
}
}
} // end paint
} // end FunctGraphCanvas
} // end Function Grapher
Tatiana_Konstantinova
Greenhorn

Joined: Nov 28, 2000
Posts: 7
As I remember, getSize() is a member of class Graphics, so you can use it only with Graphics.
Jamie Cole
Ranch Hand

Joined: Feb 03, 2000
Posts: 36
That was my first thought in trying to understand this, but getSize() is a member of Component, not Graphics, which makes me wonder why it won't find the size of the component, in this case, the canvas, that contains it, without being in the paint method.
Tatiana_Konstantinova
Greenhorn

Joined: Nov 28, 2000
Posts: 7
But you didn't defined canvas size before. For example if you define
Circle circle = new Circle(new Point(20, 35), 50);
after this you can write
Dimension dem = circle.getSize();
You also can use getSize() ini init method of the main applet,
but here is a new class and component is not initialized.
Jamie Cole
Ranch Hand

Joined: Feb 03, 2000
Posts: 36
Thank you for your ideas.
I was using the getSize() so that the graph would scale to whatever size the canvas took. If I knew, or determined, the size beforehand, I would not need the getSize() method.
Paul Bailey
Ranch Hand

Joined: Oct 20, 2000
Posts: 91
getSize() does, in fact, work in all places. The problem is that the canvas is 0x0 until it is resized.
Paul
Manfred Leonhardt
Ranch Hand

Joined: Jan 09, 2001
Posts: 1492
Hi Jamie,
Your problem stems from the fact that the canvas has no size until it has been added into a container. In your case, the BorderLayout applet will size the canvas.
One approach might be to add your FunctGraphCanvas as a component listener for itself. Then in your componentShown method you can goahead and use the getSize method.
Regards,
Manfred.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Why does getSize() need to be inside Canvas's paint method?