Java 用对象重新绘制我的面板

Java 用对象重新绘制我的面板,java,swing,repaint,Java,Swing,Repaint,我创建了一个程序,该程序应该在每次单击时绘制一个圆(随机大小和随机颜色),每个圆都将成为一个对象。我不知道发生了什么,但我的代码不起作用,我很确定我就快到了 import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.Random; public class Circle { private JFrame frame; CircleObj circleObj; R

我创建了一个程序,该程序应该在每次单击时绘制一个圆(随机大小和随机颜色),每个圆都将成为一个对象。我不知道发生了什么,但我的代码不起作用,我很确定我就快到了

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;

public class Circle
{

    private JFrame frame;
    CircleObj circleObj;
    Random  rand;
    int rColor;
    int gColor;
    int bColor;
    int radius;



    public static void main (String [] arg)
        {

        frame = new JFrame("Circles");
        frame.setBounds(200, 100, 600, 480);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());
        JPanel top = new JPanel();
        rand = new Random();

        top.addMouseListener(new MouseAdapter()
        {
            public void mouseClicked(MouseEvent e)
                {
                int xstart = e.getX();
                int ystart = e.getY();
                rColor = rand.nextInt(256);
                gColor = rand.nextInt(256);
                bColor = rand.nextInt(256);
                radius = rand.nextInt(20);
                circleObj = new CircleObj(xstart, ystart, rColor, gColor, bColor, radius);

                repaint();

                }
        });
                frame.add(top, BorderLayout.CENTER);
                frame.setVisible(true);

        }


}
这是我的CircleObj课程

import javax.swing.*;
import java.awt.*;

public class CircleObj extends JPanel

{
    private int xVal;
    private int yVal;
    private int red;
    private int green;
    private int blue;
    private int circleRadius;


    public CircleObj (int x, int y, int r, int g, int b, int rad)
        {
        xVal = x;
        yVal = y;
        red = r;
        green= g;
        blue = b;
        circleRadius = rad;

        }



        public void paintComponent (Graphics g) {
        super.paintComponent(g);
        g.setColor(new Color(red, green, blue));
        g.fillOval(xVal,yVal,circleRadius,circleRadius);
        }

}

您将鼠标侦听器添加到顶级JPanel,但何时将顶级JPanel添加到顶级窗口GUI?--在鼠标侦听器中!因此,这永远不会起作用,因为顶级JPanel最初不是GUI的一部分,只有在触发添加到它的MouseListener时才会被添加。MouseListener只在GUI上可见的组件上工作

接下来创建一个CircleObj对象,但不要在任何JComponent或JPanel的paiintComponent方法中使用它进行绘制

我很肯定我就快到了

所以不,不完全是。您将需要重新启动并执行以下操作:

  • 创建一个JPanel,该JPanel具有适当的PaintComplant方法覆盖
  • 从一开始就将此JPanel添加到GUI的JFrame
  • ArrayList
    添加到此图形JPanel
  • 更改CircleObj类,使其不扩展JPanel,但有一个将绘制它的
    public void draw(Grpahics g)
    方法
  • 向控制此图形的JPanel添加鼠标侦听器。在MouseListener中,向ArrayList添加一个新的CircleObj,并调用
    repaint()
    以获取要绘制的图形JPanel
  • 在JPanel的paintComponent覆盖中,遍历
    ArrayList
    调用每个对象的
    draw(g)
    方法
  • 读这本书
将鼠标侦听器添加到顶级JPanel,但何时将顶级JPanel添加到顶级窗口GUI?--在鼠标侦听器中!因此,这永远不会起作用,因为顶级JPanel最初不是GUI的一部分,只有在触发添加到它的MouseListener时才会被添加。MouseListener只在GUI上可见的组件上工作

接下来创建一个CircleObj对象,但不要在任何JComponent或JPanel的paiintComponent方法中使用它进行绘制

我很肯定我就快到了

所以不,不完全是。您将需要重新启动并执行以下操作:

  • 创建一个JPanel,该JPanel具有适当的PaintComplant方法覆盖
  • 从一开始就将此JPanel添加到GUI的JFrame
  • ArrayList
    添加到此图形JPanel
  • 更改CircleObj类,使其不扩展JPanel,但有一个将绘制它的
    public void draw(Grpahics g)
    方法
  • 向控制此图形的JPanel添加鼠标侦听器。在MouseListener中,向ArrayList添加一个新的CircleObj,并调用
    repaint()
    以获取要绘制的图形JPanel
  • 在JPanel的paintComponent覆盖中,遍历
    ArrayList
    调用每个对象的
    draw(g)
    方法
  • 读这本书
      这里是第二种方法。。。如何调整它并将每个圆存储在一个对象中(对象的Arraylist)

      圆环体类

      public class CircleObj extends JPanel {
          private int rColor;
          private int gColor;
          private int bColor;
          private int radius;
          private Random rand = new Random();
          private int xStart;
          private int yStart;
      
          public CircleObj () {
          addMouseListener(new MouseAdapter() {
      
              public void mouseClicked (MouseEvent e) {
      
              xStart = e.getX();
              yStart = e.getY();
              rColor = rand.nextInt(256);
              gColor = rand.nextInt(256);
              bColor = rand.nextInt(256);
              radius = rand.nextInt(20);
              System.out.println("xstart : " + xStart + ", ystart : " + yStart + ", rColor : " + rColor + ", gColor = " +
                      gColor + ", bColor: " + bColor + ", radius: " + radius);
      
              repaint();
              }
          }); // end addMouseListener
          }
      
          public void paintComponent (Graphics g) {
          super.paintComponent(g);
          g.setColor(new Color(rColor, gColor, bColor));
          g.fillOval(xStart, yStart, radius, radius);
          }
      
      }
      

      这里是第二种方法。。。如何调整它并将每个圆存储在一个对象中(对象的Arraylist)

      圆环体类

      public class CircleObj extends JPanel {
          private int rColor;
          private int gColor;
          private int bColor;
          private int radius;
          private Random rand = new Random();
          private int xStart;
          private int yStart;
      
          public CircleObj () {
          addMouseListener(new MouseAdapter() {
      
              public void mouseClicked (MouseEvent e) {
      
              xStart = e.getX();
              yStart = e.getY();
              rColor = rand.nextInt(256);
              gColor = rand.nextInt(256);
              bColor = rand.nextInt(256);
              radius = rand.nextInt(20);
              System.out.println("xstart : " + xStart + ", ystart : " + yStart + ", rColor : " + rColor + ", gColor = " +
                      gColor + ", bColor: " + bColor + ", radius: " + radius);
      
              repaint();
              }
          }); // end addMouseListener
          }
      
          public void paintComponent (Graphics g) {
          super.paintComponent(g);
          g.setColor(new Color(rColor, gColor, bColor));
          g.fillOval(xStart, yStart, radius, radius);
          }
      
      }
      

      @正如这个答案所显示的,还有很多事情要做。我建议把它分解成小块。例如,您可能希望从在JPanel上绘制一个圆开始。圆的位置和大小应该从硬编码开始,只是为了让事情变得简单。实际上,在不使用
      CircleObj
      类的情况下绘制一个圆,然后在以后添加它。从这里添加一些更复杂的东西。继续一点一点地添加,直到完成项目为止。@首先是装满鳗鱼的气垫船谢谢你。。。我根据你的建议创建了代码……我只是不知道如何将每次单击的绘制存储到对象的数组列表中。@iali87:你需要在鼠标侦听器中执行此操作。您甚至可以为绘图JPanel提供一个方法--
      addCircle(Point p)
      ,在该方法中,让绘图面板从鼠标点创建一个新的圆,然后从鼠标侦听器中调用该方法。坚持下去,你会明白的,但千万不要在没有经过逻辑思考的情况下随意猜测和抛出代码,否则你最终会得到上面所发布的代码。@Hovercraft Of Eels我回答了我的问题(根据你的建议)你认为正确吗?@iali87:如果正确与否,你很容易回答:它的行为正确吗?它是否添加了使用鼠标侦听器绘制的对象?恐怕您的鼠标听写器不会这样做,而且您没有单独的圆对象添加到图形JPanel中。@iali87正如这个答案所示,有很多事情要做。我建议把它分解成小块。例如,您可能希望从在JPanel上绘制一个圆开始。圆的位置和大小应该从硬编码开始,只是为了让事情变得简单。实际上,在不使用
      CircleObj
      类的情况下绘制一个圆,然后在以后添加它。从这里添加一些更复杂的东西。继续一点一点地添加,直到完成项目为止。@首先是装满鳗鱼的气垫船谢谢你。。。我根据你的建议创建了代码……我只是不知道如何将每次单击的绘制存储到对象的数组列表中。@iali87:你需要在鼠标侦听器中执行此操作。您甚至可以为绘图JPanel提供一个方法--
      addCircle(Point p)
      ,在该方法中,让绘图面板从鼠标点创建一个新的圆,然后从鼠标侦听器中调用该方法。坚持下去,你会明白的,但千万不要在没有经过逻辑思考的情况下随意猜测和抛出代码,否则你最终会得到上面所发布的代码。@Hovercraft Full Eels我回答了我的问题(根据你的建议),你认为这是正确的吗?@iali8