[英]Why does my method inside a class only draw the first circle but if i just use filloval method inside a for loop it displays all circles?
我正在編寫一個程序,每次單擊 Jpanel 時都會顯示一個圓圈。 我已經設置好了,我希望能夠使用我在我的圓圈 class 中創建的 drawCircle 方法在 paintComponent 方法中繪制圓圈。 我正在存儲在鏈接列表中創建的所有圈子。 然后我遍歷列表中的每個 Circle,並嘗試使用我的 Circle class 中稱為 drawCircle() 的方法。
出於某種原因,如果我嘗試在我的面板 class 的 for 循環中使用 c1.drawCircle() ,它只會繪制創建的最后一個圓圈。 但是,如果我只是在 for 循環中使用 g.fillOval(使用正確的參數從 Circle 類中獲取值)它可以正常工作並顯示所有圓圈。 為什么要這樣做,我如何正確使用 Circle class 中的方法 go
我不確定現在該嘗試什么。
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;
}
謝謝!
您的 class 的大部分結構都需要更改
您的 MyPanel 應該有一個更好的名稱來賦予其功能,可能類似於DrawingPanel
。
然后, DrawingPanel
負責管理要繪制的圓圈。 因此,通常您只需使用 ArrayList 來保存 Circle 信息。
然后,您將向 class 添加一個方法,例如addCircle(...)
以將 Circle 信息添加到 ArrayList,然后調用 repaint()。
然后在您的paintComponent(...)
方法中,您要做的第一件事就是調用 super.paintComponent(...) 來清除面板。 然后遍歷 ArrayList 並繪制所有圓圈。 將不需要 Boolean 值來檢查 class 的 state。 ArrayList 要么有圓圈,要么沒有。
您還需要一個類似clearCircles()
的方法。 這將簡單地從 ArrayList 中刪除所有 Circles 並對其自身調用 repaint() 。
您的Circle
class 不應擴展 JPanel。 它應該只是一個 class 包含繪制圓所需的信息:x/y 位置、圓的大小和圓的顏色。
現在您的框架負責顯示您的DrawingPanel
面板和按鈕。
當您單擊“清除”按鈕時,您只需調用DrawingPanel
的clearCircles()
方法。
對於您的 MouseListener,您只需調用DrawingPanel
的addCircle(...)
方法,一旦您擁有創建 Circle 實例所需的所有信息。
有關包含所有這些建議的完整工作示例,請查看自定義繪畫方法中的DrawOnComponent
示例
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.