Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
132 views
in Technique[技术] by (71.8m points)

java - 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?

I'm writing a program that displays a circle every time you click the Jpanel. I have it all set up and I want to be able to use the drawCircle method I created in my circle class to draw the circles in the paintComponent method. I'm storing all of the circles created in a linked list. Then I interate through each Circle in the list and try to use the method in my Circle class called drawCircle().

For some reason, if I try to use c1.drawCircle() in a for loop in the My panel class it only draws the last circle that was created. But if I just use g.fillOval(with the correct parameters grabbing the values from the Circle class) in the for loop it works properly and displays all the circles. Why is it doing this and how do I go about using the method in the Circle class properly

I'm unsure what to try right now.

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;


        }

Thank you!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Most of the structure of your class needs to be changed

  1. Your MyPanel should have a better name to give its functionality, maybe something like DrawingPanel.

  2. The DrawingPanel is then responsible for managing the Circles to be painted. So typically you would just use an ArrayList to hold the Circle information.

  3. Then you would add a method to the class, like addCircle(...) to add the Circle information to the ArrayList and then invoke repaint().

  4. Then in your paintComponent(...) method the first thing you do is invoke super.paintComponent(...) to clear the panel. Then you iterate through the ArrayList and paint all the Circles. There will be no need for the Boolean values to check the state of the class. The ArrayList will either have circles or it won't.

  5. You would also need a method like clearCircles(). This would simply remove all the Circles from the ArrayList and invoke repaint() on itself.

  6. Your Circle class should NOT extend JPanel. It should just be a class that contains the information need to paint the circle: x/y location, size of circle and color of circle.

  7. Now your frame is responsible of displaying your DrawingPanel and the buttons.

  8. When you click the "Clear" button you simply invoke the clearCircles() method of the DrawingPanel.

  9. For your MouseListener you simply invoke the addCircle(...) method of your DrawingPanel once you have all the information needed to create a Circle instance.

For a complete working example that incorporates all these suggestions check out the DrawOnComponent example found in Custom Painting Approaches


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...