有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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) 个答案

  1. # 1 楼答案

    你们班的大部分结构都需要改变

    1. MyPanel应该有一个更好的名称来表示它的功能,可能类似于DrawingPanel

    2. 然后DrawingPanel负责管理要绘制的圆。因此,通常只需使用ArrayList来保存圆信息

    3. 然后向类中添加一个方法,如addCircle(...),将圆信息添加到ArrayList中,然后调用repaint()

    4. 然后在paintComponent(...)方法中,您要做的第一件事就是调用super。油漆组件(…)以清除面板。然后遍历ArrayList并绘制所有圆。不需要布尔值来检查类的状态。ArrayList要么有圆,要么没有圆。

    5. 您还需要一个类似clearCircles()的方法。这将简单地从ArrayList中删除所有圆,并在其自身上调用repaint()

    6. 您的Circle类不应扩展JPanel。它应该只是一个包含绘制圆所需信息的类:x/y位置、圆的大小和圆的颜色

    7. 现在,框架负责显示DrawingPanel和按钮

    8. 单击“清除”按钮时,只需调用DrawingPanelclearCircles()方法

    9. 对于MouseListener,在获得创建循环实例所需的所有信息后,只需调用addCircle(...)DrawingPanel方法

    有关包含所有这些建议的完整工作示例,请查看Custom Painting Approaches中的DrawOnComponent示例