Почему мой метод внутри класса рисует только первый круг, но если я просто использую метод filloval внутри цикла for, он отображает все круги? - PullRequest
0 голосов
/ 19 сентября 2019

Я пишу программу, которая отображает кружок каждый раз, когда вы нажимаете Jpanel.У меня все настроено, и я хочу иметь возможность использовать метод drawCircle, который я создал в своем классе кругов, для рисования кругов в методе paintComponent.Я храню все круги, созданные в связанном списке.Затем я перебираю каждый круг в списке и пытаюсь использовать метод в моем классе Circle, называемый drawCircle ().

По какой-то причине, если я пытаюсь использовать c1.drawCircle () в цикле for в классе My panel, он рисует только последний созданный круг.Но если я просто использую g.fillOval (с правильными параметрами, получающими значения из класса Circle) в цикле for, он работает правильно и отображает все круги.Почему это происходит, и как мне правильно использовать метод в классе 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 голос
/ 19 сентября 2019

Большая часть структуры вашего класса должна быть изменена

  1. Ваша MyPanel должна иметь более подходящее имя, чтобы дать ей функциональность, например, DrawingPanel.

  2. В этом случае DrawingPanel отвечает за управление нарисованными кругами.Поэтому, как правило, вы просто используете ArrayList для хранения информации о круге.

  3. Затем вы добавите в класс метод, например addCircle(...), чтобы добавить информацию о Circle в ArrayList, а затем вызовите repaint ().

  4. Затем в вашем методе paintComponent(...) первое, что вы делаете, это вызываете super.paintComponent (...) для очистки панели.Затем вы перебираете ArrayList и рисуете все круги.Не будет необходимости в булевых значениях для проверки состояния класса.ArrayList будет иметь круги или не будет.

  5. Вам также понадобится метод, подобный clearCircles().Это просто удалит все Круги из ArrayList и вызовет repaint () для себя.

  6. Ваш класс Circle НЕ ДОЛЖЕН расширять JPanel.Это должен быть просто класс, содержащий информацию, необходимую для рисования круга: x / y местоположение, размер круга и цвет круга.

  7. Теперь ваша рамка отвечает за отображение вашего DrawingPanel и кнопки.

  8. Когда вы нажимаете кнопку «Очистить», вы просто вызываете метод clearCircles() DrawingPanel.

  9. Для вашего MouseListener вы просто вызываете метод addCircle(...) вашего DrawingPanel, как только у вас есть вся информация, необходимая для создания экземпляра Circle.

Для полного рабочего примера, включающегоВсе эти предложения приведены в примере DrawOnComponent, приведенном в Индивидуальные подходы к рисованию

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...