java为什么我在类中的方法只画第一个圆,但如果我在for循环中只使用filloval方法,它会显示所有圆?
我正在编写一个程序,每次单击Jpanel时都会显示一个圆圈。我已经全部设置好了,我希望能够使用我在circle类中创建的drawCircle方法在paintComponent方法中绘制圆。我将在链表中存储创建的所有圆圈。然后我遍历列表中的每个圆,并尝试使用名为drawCircle()的Circle类中的方法
出于某种原因,如果我尝试使用c1。drawCircle()在My panel类的for循环中,它只绘制创建的最后一个圆。但是如果我只是在for循环中使用g.fillOval(使用从Circle类获取值的正确参数),它会正常工作并显示所有的圆。为什么要这样做?我如何正确地使用Circle类中的方法
我不知道现在该试什么
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.LinkedList;
public class MouseTest {
private int borderWidth = 20;
private JFrame frame;
private boolean tracking;
private boolean start;
private boolean clearBol;
private int xstart;
private int ystart;
private int xend;
private int yend;
private LinkedList<Circle> circles;
public MouseTest() {
tracking = false;
start = false;
circles = new LinkedList<Circle>();
frame = new JFrame();
frame.setBounds(250, 98, 600, 480);
frame.setTitle("Window number three");
Container cp = frame.getContentPane();
JButton clear = new JButton("Clear");
JToggleButton circleButton = new JToggleButton()("Circles");
JToggleButton drawButton = new JToggleButton("Draw");
ButtonGroup circleOrDraw = new ButtonGroup();
MyPanel pane = new MyPanel();
clear.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
clearBol = true;
frame.repaint();
}
});
JPanel top = new JPanel();
top.setLayout(new FlowLayout());
top.add(clear);
circleOrDraw.add(circleButton);
circleOrDraw.add(drawButton);
top.add(circleOrDraw);
cp.add(top, BorderLayout.NORTH);
cp.add(pane, BorderLayout.CENTER);
pane.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
xstart = e.getX();
ystart = e.getY();
start = false;
}
public void mouseReleased(MouseEvent e) {
xend = e.getX();
yend = e.getY();
if (xend < xstart) {
int tmp = xstart;
xstart = xend;
xend = tmp;
}
if (yend < ystart) {
int tmp = ystart;
ystart = yend;
yend = tmp;
}
start = true;
frame.repaint();
}
});
pane.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
if (tracking) {
int x = e.getX();
int y = e.getY();
msg("(" + x + ", " + y + ")");
}
}
});
frame.setVisible(true);
} // constructor
public static void main(String[] arg) {
MouseTest first = new MouseTest();
} // main
public void msg(String s) {
System.out.println(s);
}
public void trackMouse() {
tracking = !tracking;
} // trackMouse
public class Circle extends JPanel {
Graphics g;
int x;
int y;
int r;
Color color;
public Circle(Graphics g, int x, int y, int r) {
this.g = g;
this.x = x;
this.y = y;
this.r = r;
int red = (int) (256 * Math.random());
int green = (int) (256 * Math.random());
int blue = (int) (256 * Math.random());
this.color = new Color(red, green, blue);
}
public void drawCircle() {
int x2 = x - (r / 2);
int y2 = y - (this.r / 2);
g.setColor(color);
g.fillOval(x2, y2, this.r, this.r);
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Color getColor() {
return color;
}
public int getR() {
return r;
}
}
public class MyPanel extends JPanel {
public void paintComponent(Graphics g) {
if (start) {
circles.add(new Circle(g, xend, yend,
(int) ((250 * Math.random() + 4))));
//Area where I'm having issues
for (Circle c1 : circles) {
msg("" + c1.getX());
// this method that I created in the circle class will only draw the first circle
//c1.drawCircle();
int r = c1.getR();
int x = c1.getX();
int y = c1.getY();
g.setColor(c1.getColor());
g.fillOval((c1.getX() - (r / 2)), (c1.getY() - (r / 2)),
r, r); // this will display all the circles
}
int size = circles.size();
msg(size + " Size");
msg("" + circles.getLast().getX());
}
if (clearBol) {
super.paintComponent(g);
circles.clear();
clearBol= false;
}
谢谢大家!
# 1 楼答案
你们班的大部分结构都需要改变
MyPanel应该有一个更好的名称来表示它的功能,可能类似于
DrawingPanel
然后
DrawingPanel
负责管理要绘制的圆。因此,通常只需使用ArrayList来保存圆信息然后向类中添加一个方法,如
addCircle(...)
,将圆信息添加到ArrayList中,然后调用repaint()然后在
paintComponent(...)
方法中,您要做的第一件事就是调用super。油漆组件(…)以清除面板。然后遍历ArrayList并绘制所有圆。不需要布尔值来检查类的状态。ArrayList要么有圆,要么没有圆。您还需要一个类似
clearCircles()
的方法。这将简单地从ArrayList中删除所有圆,并在其自身上调用repaint()您的
Circle
类不应扩展JPanel。它应该只是一个包含绘制圆所需信息的类:x/y位置、圆的大小和圆的颜色现在,框架负责显示
DrawingPanel
和按钮单击“清除”按钮时,只需调用
DrawingPanel
的clearCircles()
方法对于MouseListener,在获得创建循环实例所需的所有信息后,只需调用
addCircle(...)
的DrawingPanel
方法有关包含所有这些建议的完整工作示例,请查看Custom Painting Approaches中的
DrawOnComponent
示例