在java中创建自己的paint方法

时间:2015-07-11 13:43:27

标签: java swing paint

我想创建一个在面板上创建5个球的方法。有人可以帮我解决这个问题,使用paint组件方法或创建我自己的draw方法。正如你可以看到的那样,我有一个带有for循环的paint组件方法,它将循环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();
    }

}

在我的paintComponent方法中,我创建了一个for循环,我想在其中创建5个球,但屏幕上只创建了一个。

1 个答案:

答案 0 :(得分:1)

根据我的意见建议:

  1. 摆脱Graphics g变量,因为这只会伤害你。
  2. 考虑创建一个非GUI Ball类,它不扩展任何Swing组件并具有自己的paint(Graphics)方法。
  3. 如果您需要5个球,请在AllBalls类中创建一个Ball对象数组。
  4. 在paintComponent中,通过调用paint或draw方法(无论你为方法命名)迭代遍历Balls绘制每一个。
  5. 如果您需要移动球,请在Swing Timer中移动球,然后调用repaint()。无论你做什么,在paintComponent方法中调用repaint(),因为这会导致方法的混淆,并导致完全不受控制的动画。此方法应仅用于绘画和绘画,而不适用于动画或代码逻辑。改为使用Swing Timer。
  6. 也不要在paintComponent中随机化你的球位置,这是在现在删除的答案中提出的另一个建议。同样,paintComponent应仅用于绘画和绘画,不应用于程序逻辑或更改类的状态。随机化应该在你的Swing Timer或游戏循环中。
  7. 例如:

    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();
             }
          });
       }
    }