簡體   English   中英

為什么我在 class 中的方法只繪制第一個圓圈,但如果我只是在 for 循環中使用填充方法,它會顯示所有圓圈?

[英]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 的大部分結構都需要更改

  1. 您的 MyPanel 應該有一個更好的名稱來賦予其功能,可能類似於DrawingPanel

  2. 然后, DrawingPanel負責管理要繪制的圓圈。 因此,通常您只需使用 ArrayList 來保存 Circle 信息。

  3. 然后,您將向 class 添加一個方法,例如addCircle(...)以將 Circle 信息添加到 ArrayList,然后調用 repaint()。

  4. 然后在您的paintComponent(...)方法中,您要做的第一件事就是調用 super.paintComponent(...) 來清除面板。 然后遍歷 ArrayList 並繪制所有圓圈。 將不需要 Boolean 值來檢查 class 的 state。 ArrayList 要么有圓圈,要么沒有。

  5. 您還需要一個類似clearCircles()的方法。 這將簡單地從 ArrayList 中刪除所有 Circles 並對其自身調用 repaint() 。

  6. 您的Circle class 不應擴展 JPanel。 它應該只是一個 class 包含繪制圓所需的信息:x/y 位置、圓的大小和圓的顏色。

  7. 現在您的框架負責顯示您的DrawingPanel面板和按鈕。

  8. 當您單擊“清除”按鈕時,您只需調用DrawingPanelclearCircles()方法。

  9. 對於您的 MouseListener,您只需調用DrawingPaneladdCircle(...)方法,一旦您擁有創建 Circle 實例所需的所有信息。

有關包含所有這些建議的完整工作示例,請查看自定義繪畫方法中的DrawOnComponent示例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM