• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

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

 
Jamie Cole
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As I remember, getSize() is a member of class Graphics, so you can use it only with Graphics.
 
Jamie Cole
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 36
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 91
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 1492
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic