How can I add shapes automatically in paintComponent?
As a beginner, whenever I want to add graphical shapes inside the frame I do something like this:
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.fillRect(0, 0, 10, 10);
g.fillOval(10,10,10,10);
}
How do I draw an unlimited number of shapes automatica开发者_运维技巧lly inside the frame? If I follow the way I did above I only have a limited number of shapes(Rect, Oval and nothing else).
I'm looking for something different, for example, whenever a method addStuff(x, y)
has called, it draws "Stuff" automatically at the coordinate x and y without having to edit anything inside paintComponent
manually again.
I used to do this with the acm package and it was easy. Just like the code below.
for (int i = 0; i < NCIRCLES; i++) {
double r = rgen.nextDouble(MIN_RADIUS, MAX_RADIUS);
double x = rgen.nextDouble(0, getWidth() - 2 * r);
double y = rgen.nextDouble(0, getHeight() - 2 * r);
GOval circle = new GOval(x, y, 2 * r, 2 * r);
circle.setFilled(true);
circle.setColor(rgen.nextColor());
add(circle);
}
As you can see above, I can add as many circles as I want, I know it can take pages to explain this but I just want a brief instruction on how to create something similar to the code above without relying on acm package.
I would use an abstract class to define this behavior.
abstract class OpalDraw {
protected int x1, y1, x2, y2;
protected OpalDraw(int x1, int y1, int x2, int y2) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
abstract public void draw(Graphics g);
}
class OpalOval {
public OpalOval(int x1, int y1, int x2, int y2) { super(x1,y1,x2,y1); }
public void draw(Graphics g) {
g.drawOval(x1,y1,x2,y1);
}
}
class OpalRect {
public OpalRect(int x1, int y1, int x2, int y2) { super(x1,y1,x2,y1); }
public void draw(Graphics g) {
g.drawRect(x1,y1,x2,y1);
}
}
Then in your painting container you can have
addOval(int x1, int y1, int x2, int y2) {
myDraws.add(new OpalOval(x1,x2,y1,y2);
}
addRect(int x1, int y1, int x2, int y2) {
myDraws.add(new OpalRect(x1,x2,y1,y2);
}
Then later inside paintComponent(Graphics)
you can
for(OpalDraw draw : myDraws) draw.draw(g);
In your class extending JFrame
, add a private member like
private ArrayList<Shape> shapes = new ArrayList<Shape>();
and your methods, for example
public void addRectangle(int x, int y, int with, int height) {
shapes.add(new Rectangle(x, y, width, height));
}
Then, in your paintBackground
method, have something like
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (Shape shape : shapes) {
if (shape instanceof Rectangle2D) {
g.drawRect(shape.getX(), shape.getY(), shape.getWidth(), shape.getHeight());
} else if (shape instanceof Ellipse2D) {
// ...
} // else if ...
// etc.
}
}
As a beginner, this should be fairly easy to understand. A yet better solution would be to have custom shape interface (ie. MyShape
) with a draw(Graphics g)
method, and implement your shapes from that interface (Circle implements MyShape
, Square implements MyShape
, etc.). Then, your ArrayList<Shape> shapes
could become ArrayList<MyShape> shapes
and your paintBackground
method would just invoke the draw
method of very MyShape
items.
精彩评论