drawingPanel颜色随位移而变化 [英] drawingPanel color change with displacement

查看:220
本文介绍了drawingPanel颜色随位移而变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用JGrasp,在drawingPanel中,我试图创建一个在屏幕上移动时会改变颜色的球.现在,我有:

I'm using JGrasp, and in drawingPanel, I'm trying to create a ball that changes colors as it moves across the screen. Right now, I've got:

for (int i = 10; i<=i; i++) {
    Color c = new Color(i*i, 0, 0);
    pen.setColor(c);

我的完整简化代码是:

import java.awt.*;
import java.util.*;
import java.awt.Color;

public class BallSample {
   public static final int SIZE = 30;
   public static final int HALF = SIZE / 2;

   public static void main(String[] args) {
      Scanner console = new Scanner(System.in);

      DrawingPanel panel = new DrawingPanel(1000, 1000);
      panel.setBackground(Color.CYAN);
      Graphics pen = panel.getGraphics();

      for (int i = 10; i<=i; i++) {
         Color c = new Color(i*i, 0, 0);
         pen.setColor(c);
         pen.fillOval(500 - HALF, 500 - HALF, SIZE, SIZE);

         double xDisplacement = 30 * Math.cos(30);
         double yDisplacement = 30 * Math.sin(30) * -1;
         double x = 500.0;
         double y = 500.0;

         for (int j = 1; j <= 100; j++) {
            x = x + xDisplacement;
            y = y + yDisplacement;
         if (x <= 0 || x >= 1000) {
            xDisplacement = xDisplacement * -1;
         }
         if (y <= 0 || y >= 1000) {
            yDisplacement = yDisplacement * -1;
         }
            pen.fillOval((int) x - HALF, (int) y - HALF, SIZE, SIZE);

            panel.sleep(50);
         }      
      }
   }
}

我希望这已经足够简化了.

I hope that's simplified enough.

推荐答案

具有

After having some issues in the following code, I was able to create a color-changing ball example.

首先,拥有panel.sleep(50);使我思考(并且我通过 DrawingPanel 您在评论中发布的类链接)可能会很危险,因此最好使用 Swing Timer 相反,但是我不假装使用或阅读所有类,因为它太长了,因此在这里发布的示例中,我将使用Swing Timer方法.

First of all, having panel.sleep(50); makes me think (and I confirm with the DrawingPanel class link you posted in the comments) could become dangerous, it would be better to use a Swing Timer instead, however I don't pretend on using or read all the class as it's too long, so in the example I post here I'll be using the Swing Timer approach.

此外,我不确定为什么要调用 new Color(int rgb) 带有随机int(介于0和255之间)的构造函数不会更新或使用这些设置创建新的Color,然后在读取

Also, I'm not sure why calling new Color(int rgb) constructor with a random int (between 0 and 255) doesn't update or create a new Color with those settings, then after reading this answer and another one (I lost its link, sorry), you can use new Color(float r, float g, float b), so you may use it with a random number up to 256.

您还可以将方法基于MVC模式,其中包括一个包含坐标和Color的Model Ball类,一个将随着时间推移绘制球的View JPanel和一个Controller也会随着时间改变球的坐标和颜色.

You can also base your approach to a MVC pattern, having a Model Ball class which contains the coords and the Color it will have, a View JPanel that will draw the ball over time and a Controller that will change the ball's coords and color overtime as well.

免责声明:此示例仅水平移动球,并且不验证屏幕上是否显示球,您需要使此示例适应您自己的需求.

Disclaimer: This example just moves the ball horizontally and doesn't validate whether it's on the screen or not, you need to adapt this example to your own needs.

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.Random;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class ChangingColorBall {
    private JFrame frame;
    private Timer timer;
    private BallPane ballPane;
    private Ball ball;
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new ChangingColorBall()::createAndShowGui); //We place our program on the EDT
    }
    
    private void createAndShowGui() {
        frame = new JFrame(getClass().getSimpleName());
        ball = new Ball();
        ballPane = new BallPane(ball);
        
        timer = new Timer(100, e -> { //This Timer will execute every 100ms and will increase ball's X coord and paint it again.
            ball.increaseX(); //This method increases X coord and changes ball's color on the model
            ballPane.revalidate();
            ballPane.repaint();
        });
        
        frame.add(ballPane);
        
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        timer.start(); //We start the timer
    }
    
    class Ball {
        private int xCoord;
        private static final int Y = 50;
        private static final int SIZE = 20;
        private Color color;
        private Random r;
        
        public void increaseX() {
            xCoord += 10; //Increases X coord
            r = new Random();
            color = new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256)); //Generates a new random color
        }
        
        public int getXCoord() {
            return xCoord;
        }

        public void setXCoord(int xCoord) {
            this.xCoord = xCoord;
        }

        public Color getColor() {
            return color;
        }

        public void setColor(Color color) {
            this.color = color;
        }
    }
    
    @SuppressWarnings("serial")
    class BallPane extends JPanel {
        private Ball ball;
        
        public BallPane(Ball ball) {
            this.ball = ball;
        }
        
        @Override
        protected void paintComponent(Graphics g) { //This method paints the ball according to the color it has and the actual coords it has
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            
            g2d.setColor(ball.getColor());
            g2d.fillOval(ball.getXCoord(), Ball.Y, Ball.SIZE, Ball.SIZE);
        }
        
        @Override
        public Dimension getPreferredSize() { //We should not call `.setSize(...)` method, so we override this one and call `.pack();` 
            return new Dimension(200, 100);
        }
    }
}

注意

请注意不要将坐标称为xy,或者至少不要将其getter和setter称为getX()getY(),否则您可能会遇到我开头提到的问题这个答案.

Note

Be aware to not call your coords as x or y or at least don't call their getters and setters as getX() or getY() or you could run into the issue I linked at the beginning of this answer.

这是一个GUI外观的示例,我无法在计算机中执行GIF,但是最好将代码复制粘贴并查看其工作方式.

Here's an example of how the GUI looks like, I can't do GIFs in my computer but it's better if you copy-paste the code and see how it works.

要更深入地了解自定义绘画在Swing中的工作方式,请查看Oracle的课程:执行自定义绘画在AWT和Swing中进行绘画教程.

For a deeper understanding on how custom painting works in Swing, check Oracle's Lesson: Performing Custom Painting and Painting in AWT and Swing tutorials.

这篇关于drawingPanel颜色随位移而变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆