简体   繁体   English

在Java中创建我自己的绘画方法

[英]Creating my own paint method in java

I want to create a method that creates 5 balls on a panel. 我想创建一个在面板上创建5个球的方法。 Can somebody please help me get around this using the paint component method or creating my own draw method. 有人可以帮助我使用paint组件方法或创建自己的draw方法来解决此问题。 As you can see bellow, i have a paint component method with a for loop that will loop 5 and create a ball in a random location, but unfortunately only one ball is being created. 正如您在下面看到的那样,我有一个带有for循环的paint component方法,该方法将循环5并在一个随机位置创建一个球,但是不幸的是,仅创建了一个球。

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

public class AllBalls extends JPanel {
    int Number_Ball=5;
    int x,y;
    Graphics g;
    AllBalls(){
        Random r = new Random();
        x=r.nextInt(320);
        y=r.nextInt(550);
    }
public static JFrame frame;
    public static void main(String[] args) {
        AllBalls a= new AllBalls();
        frame= new JFrame("Bouncing Balls");
        frame.setSize(400,600);
        frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.add(a);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for(int i=0;i<Number_Ball;i++){
            g.fillOval(x, y, 30, 30);
        }
        repaint();
    }

}

In my paintComponent method, i created a for loop in which i wanted 5 ball to be created, but only one is being created on the screen. 在我的paintComponent方法中,我创建了一个for循环,其中希望创建5个球,但是在屏幕上只创建了一个。

Recommendations as per my comments: 根据我的意见的建议:

  1. Get rid of the Graphics g variable as that will only hurt you. 摆脱Graphics g变量,因为这只会伤害您。
  2. Consider creating a non-GUI Ball class, one that does not extend any Swing component and has its own paint(Graphics) method. 考虑创建一个非GUI Ball类,该类不扩展任何Swing组件并具有自己的paint(Graphics)方法。
  3. If you need 5 balls, create an array of Ball objects in your AllBalls class. 如果需要5个球,请在AllBalls类中创建一个Ball对象数组。
  4. In paintComponent, iterate through the Balls painting each one by calling its paint or draw method (whatever you name the method). 在paintComponent中,通过调用其paint或draw方法(无论您使用哪种方法)来遍历Balls绘画每个对象。
  5. If you need to move the balls, do so in a Swing Timer that moves the balls and then calls repaint(). 如果需要移动球,请在Swing计时器中移动球,然后调用repaint()。 Whatever you do, do not call repaint() within the paintComponent method as this results in a bastardization of the method, and results in a completely uncontrolled animation. 无论做什么,都不要在paintComponent方法内调用repaint() ,因为这会导致方法的混用,并导致完全不受控制的动画。 This method should be for painting and painting only and not for animation or code logic. 此方法应仅用于绘画,而不能用于动画或代码逻辑。 Use the Swing Timer instead. 请改用Swing计时器。
  6. Also don't randomize your ball locations within paintComponent, another recommendation made in a now-deleted answer. 另外,不要在paintComponent中随机放置球的位置,这是现已删除的答案中提出的另一项建议。 Again, paintComponent should be for painting and painting only and not for program logic or to change the state of your class. 同样,paintComponent应该仅用于绘画,而不能用于程序逻辑或更改类的状态。 The randomization should be within your Swing Timer or game loop. 随机化应该在您的Swing Timer或游戏循环中。

For example: 例如:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.*;

@SuppressWarnings({"serial", "unused"})
public class BallImages extends JPanel {
   private static final int PREF_W = 800;
   private static final int PREF_H = PREF_W;
   private static final int BALL_COUNT = 15;
   private static final Color[] COLORS = { Color.RED, Color.BLACK, Color.BLUE,
         Color.CYAN, Color.GREEN, Color.ORANGE, Color.PINK, Color.WHITE,
         Color.MAGENTA, Color.YELLOW };
   private static final int MIN_SPEED = 2;
   private static final int MAX_SPEED = 10;
   private static final int MIN_WIDTH = 10;
   private static final int MAX_WIDTH = 30;
   private static final int TIMER_DELAY = 15;
   private List<Ball> balls = new ArrayList<>();
   private Random random = new Random();

   public BallImages() {
      for (int i = 0; i < BALL_COUNT; i++) {
         int ballWidth = MIN_WIDTH + random.nextInt(MAX_WIDTH - MIN_WIDTH);
         Color ballColor = COLORS[random.nextInt(COLORS.length)];
         int ballX = ballWidth / 2 + random.nextInt(PREF_W - ballWidth / 2);
         int ballY = ballWidth / 2 + random.nextInt(PREF_H - ballWidth / 2);
         double direction = 2 * Math.PI * Math.random();
         double speed = MIN_SPEED + random.nextInt(MAX_SPEED - MIN_SPEED);
         Ball ball = new Ball(ballWidth, ballColor, ballX, ballY, direction,
               speed);
         balls.add(ball);
      }

      new Timer(TIMER_DELAY, new TimerListener()).start();
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
      for (Ball ball : balls) {
         ball.draw(g2);
      }
   }

   @Override
   // set the component's size in a safe way
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

   private class TimerListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         if (!BallImages.this.isDisplayable()) {
            ((Timer) e.getSource()).stop();
         }
         for (Ball ball : balls) {
            ball.move(PREF_W, PREF_H);
         }
         repaint();
      }
   }

   private class Ball {
      private int width;
      private Color color;
      private double x;
      private double y;
      private double direction;
      private double speed;
      private double deltaX;
      private double deltaY;

      public Ball(int width, Color color, int x, int y, double direction,
            double speed) {
         this.width = width;
         this.color = color;
         this.x = x;
         this.y = y;
         this.direction = direction;
         this.speed = speed;

         deltaX = speed * Math.cos(direction);
         deltaY = speed * Math.sin(direction);
      }

      public int getWidth() {
         return width;
      }

      public Color getColor() {
         return color;
      }

      public double getX() {
         return x;
      }

      public double getY() {
         return y;
      }

      public double getDirection() {
         return direction;
      }

      public double getSpeed() {
         return speed;
      }

      public void draw(Graphics2D g2) {
         g2.setColor(color);
         int x2 = (int) (x - width / 2);
         int y2 = (int) (y - width / 2);
         g2.fillOval(x2, y2, width, width);
      }

      public void move(int containerWidth, int containerHeight) {
         double newX = x + deltaX;
         double newY = y + deltaY;

         if (newX - width / 2 < 0) {
            deltaX = Math.abs(deltaX);
            newX = x + deltaX;
         }
         if (newY - width / 2 < 0) {
            deltaY = Math.abs(deltaY);
            newY = y + deltaY;
         }

         if (newX + width / 2 > containerWidth) {
            deltaX = -Math.abs(deltaX);
            newX = x + deltaX;
         }
         if (newY + width / 2 > containerHeight) {
            deltaY = -Math.abs(deltaY);
            newY = y + deltaY;
         }

         x = newX;
         y = newY;

      }
   }

   private static void createAndShowGui() {
      BallImages mainPanel = new BallImages();

      JFrame frame = new JFrame("BallImages");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.setResizable(false);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM