如何生成多个圆圈的形状和动画这些形状下去框架 [英] How to generate multiple circle shapes and animate those shapes going down the frame

查看:171
本文介绍了如何生成多个圆圈的形状和动画这些形状下去框架的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法点击框面板时产生多个椭圆形。我要的是,这将产生许多椭圆形的形状和这些形状会向下移动。一的要求是使用两个多线程。然而,在我的情况,我创建的程序是这样的,它只会生成一个椭圆形的位置随机变化。任何人都可以请帮我一本。

 包ovalrandomcolors;进口java.awt.Color中;
进口java.awt.Component中;
进口java.awt.Graphics;
进口java.awt.Graphics2D中;
进口的java.util.List;
进口java.awt.Shape中;
进口java.awt.event.MouseAdapter;
进口java.awt.event.MouseEvent中;
进口java.awt.geom.Ellipse2D;
进口的java.util.ArrayList;
进口java.util.Collections中;
进口java.util.logging.Level中;
进口java.util.logging.Logger中;
进口javax.swing.JFrame中;
进口javax.swing.JPanel中;
进口javax.swing.SwingUtilities中;公共类OvalRandomColors继承JPanel {    私人INT ovalX = 50;
    私人INT ovalY = 50;
    私人INT ovalPositionX = 250;
    私人INT ovalPositionY = 250;
    私人色彩的颜色= Color.YELLOW;    公共OvalRandomColors(){
        的setBackground(Color.DARK_GRAY);
    }
    @覆盖
    公共无效的paintComponent(图形G){
        super.paintComponent方法(G);
        g.setColor(颜色);
        g.fillOval(ovalPositionX,ovalPositionY,ovalX,ovalY);        g.setColor(颜色);
        g.fillOval(ovalPositionX,ovalPositionY,ovalX,ovalY);    }    公共静态无效的主要(字串[] args){
        SwingUtilities.invokeLater(Runnable的新(){            @覆盖
            公共无效的run(){
               JFrame的帧=新的JFrame();
               最后OvalRandomColors椭圆形=新OvalRandomColors();
               oval.addMouseListener(新MouseAdapter(){
                   @覆盖
                   公共无效的mouseClicked(的MouseEvent E){
                       OvalWithThreading firstThread =新OvalWithThreading(椭圆形);
                       OvalWithThreading secondThread =新OvalWithThreading(椭圆形);                       线程首先=新主题(firstThread);
                       螺纹第二=新主题(secondThread);
                       second.start();
                       first.start();
                   }
               });               frame.add(椭圆形);
               frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
               frame.setSize(500,700);
               frame.setVisible(真);
            }
        });
    }
    公共无效updateOval(){        INT R =(INT)(的Math.random()* 255);
        INT G =(INT)(的Math.random()* 255);
        INT B =(int)的(的Math.random()* 255);        颜色=新的色彩(R,G,B);        ovalPositionX =(INT)(的Math.random()* 78);
        ovalPositionY =(INT)(的Math.random()* 245);        animateOval();
        重绘();
    }
    公共无效animateOval(){
           // ovalPositionX + = 30;
            ovalPositionY + = 30;
    }    公共静态类OvalWithThreading实现Runnable {        私人最终OvalRandomColors ovalShape;
        公共OvalWithThreading(OvalRandomColors OS){
            this.ovalShape = OS;
        }
        @覆盖
        公共无效的run(){
            对于(;;){
                    ovalShape.updateOval();
                尝试{
                视频下载(1000);
            }赶上(InterruptedException的前){
                。Logger.getLogger(OvalRandomColors.class.getName())日志(Level.SEVERE,空,前);
                }
            }
        }
    }
}


解决方案

让我们开始,Swing是不是安全,所以有另一个其中更新对象的该UI取决于渲染状态需要一些严肃的考虑。通常情况下,我建议使用Swing的定时的SwingWorker 来做到这一点,但这些都不是的要求

为了渲染多个对象,你需要一些方法来存储它们,这样你就可以更新自己的状态和呈示它们。最简单的解决方案是一个列表,你可以看到的集合资源了解更多详情。

DropBalls

现在,如果你还需要管理的颜色,你可以看看我如何管理的增量为每个形状和应该给你一个想法,做了

 进口java.awt.Dimension中;
进口java.awt.EventQueue中;
进口java.awt.Graphics;
进口java.awt.Graphics2D中;
进口java.awt.Rectangle中;
进口java.awt.Shape中;
进口java.awt.event.MouseAdapter;
进口java.awt.event.MouseEvent中;
进口java.awt.geom.Ellipse2D;
进口java.awt.geom.Rectangle2D中;
进口的java.util.ArrayList;
进口的java.util.HashMap;
进口java.util.Iterator的;
进口的java.util.List;
进口的java.util.Map;
进口java.util.concurrent.locks.ReentrantLock中;
进口javax.swing.JFrame中;
进口javax.swing.JPanel中;
进口javax.swing.UIManager中;
进口javax.swing.UnsupportedLookAndFeelException;公共类的测试{    公共静态无效的主要(字串[] args){
        新的测试();
    }    公开测试(){
        EventQueue.invokeLater(新的Runnable(){
            @覆盖
            公共无效的run(){
                尝试{
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                }赶上(ClassNotFoundException的| InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException前){
                    ex.printStackTrace();
                }                JFrame的帧=新的JFrame(测试);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(新TestPane());
                frame.pack();
                frame.setLocationRelativeTo(NULL);
                frame.setVisible(真);
            }
        });
    }    公共类TestPane继承JPanel {        私人的ReentrantLock shapesLock =新的ReentrantLock();
        私人列表<&Ellipse2D的GT;形状;        公共TestPane(){
            形状=新的ArrayList<>(25);
            addMouseListener将(新MouseAdapter(){
                @覆盖
                公共无效的mouseClicked(的MouseEvent E){
                    shapesLock.lock();
                    尝试{
                        shapes.add(新Ellipse2D.Double(e.getX() - 5,e.getY() - 5,10,10));
                    } {最后
                        shapesLock.unlock();
                    }
                }
            });            线程t =新主题(新的Runnable(){
                私人地图<形状,双>三角洲=新的HashMap<>();                @覆盖
                公共无效的run(){
                    而(真){
                        尝试{
                            shapesLock.lock();
                            尝试{
                                矩形containerBounds =的getBounds();
                                containerBounds.setLocation(0,0);
                                迭代器<&Ellipse2D的GT;它= shapes.iterator();
                                而(it.hasNext()){
                                    外形Ellipse2D的= it.next();
                                    矩形边界= shape.getBounds2D();
                                    双Y = bounds.getY();
                                    双三角翼= d​​eltas.get(形状);
                                    如果(增量== NULL){
                                        三角洲= 0D;
                                    }
                                    Y + =增量;
                                    shape.setFrame(bounds.getX()中,Y,bounds.getWidth(),bounds.getHeight());
                                    如果(containerBounds.contains(shape.getBounds())){
                                        三角洲= Math.min(增量+ 0.25,6D);
                                        deltas.put(形状,三角形);
                                    }其他{
                                        it.remove();
                                    }
                                }
                            } {最后
                                shapesLock.unlock();
                            }
                            重绘();
                            视频下载(40);
                        }赶上(InterruptedException的前){
                        }
                    }
                }
            });
            t.se​​tDaemon(假);
            t.start();
        }        @覆盖
        公共尺寸的get preferredSize(){
            返回新尺寸(200,200);
        }        @覆盖
        保护无效paintComponent(图形G){
            super.paintComponent方法(G);
            Graphics2D的G2D =(Graphics2D的)g.create();
            shapesLock.lock();
            尝试{
                对于(形状Ellipse2D的:形状){
                    g2d.fill(形状);
                }
            } {最后
                shapesLock.unlock();
            }
            g2d.dispose();
        }    }}

I am having trouble generating multiple oval shapes when clicking the panel of the frame. What I want is that it will generate many oval shapes and those shapes will move downward. One of the requirement is to use two multi threading. However in my case, the program I created is that, it will only generate one oval shape and the position is randomly changing. Can anyone please help me one this.

package ovalrandomcolors;

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.List;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.Collections;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class OvalRandomColors extends JPanel{

    private int ovalX = 50;
    private int ovalY =50;
    private int ovalPositionX = 250;
    private int ovalPositionY = 250;
    private Color color = Color.YELLOW;

    public OvalRandomColors(){
        setBackground(Color.DARK_GRAY);
    }
    @Override
    public void paintComponent(Graphics g){
        super.paintComponent(g);


        g.setColor(color);
        g.fillOval(ovalPositionX, ovalPositionY, ovalX, ovalY);

        g.setColor(color);
        g.fillOval(ovalPositionX, ovalPositionY, ovalX, ovalY);

    }

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

            @Override
            public void run() {
               JFrame frame = new JFrame();
               final OvalRandomColors oval = new OvalRandomColors();
               oval.addMouseListener(new MouseAdapter(){
                   @Override
                   public void mouseClicked(MouseEvent e){
                       OvalWithThreading firstThread = new OvalWithThreading(oval);
                       OvalWithThreading secondThread = new OvalWithThreading(oval);

                       Thread first = new Thread(firstThread);
                       Thread second = new Thread(secondThread);
                       second.start();
                       first.start();
                   }
               });

               frame.add(oval);
               frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
               frame.setSize(500,700);
               frame.setVisible(true);
            }  
        });      
    }


    public void updateOval(){

        int r = (int)(Math.random() * 255);
        int g = (int) (Math.random() * 255);
        int b = (int)(Math.random() * 255);

        color = new Color(r,g,b);

        ovalPositionX = (int)(Math.random() * 78);
        ovalPositionY = (int) (Math.random() * 245);

        animateOval();
        repaint();
    }
    public void animateOval(){
           // ovalPositionX += 30;
            ovalPositionY += 30;
    }

    public static class OvalWithThreading implements Runnable{

        private final OvalRandomColors ovalShape;
        public OvalWithThreading(OvalRandomColors oS){
            this.ovalShape = oS;
        }
        @Override
        public void run() {
            for(;;){
                    ovalShape.updateOval();
                try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(OvalRandomColors.class.getName()).log(Level.SEVERE, null, ex);
                }
            }           
        }       
    }   
}

解决方案

Let's start with, Swing is not Thread safe, so having another Thread which update the state of objects which the UI depends to render requires some serious considerations. Normally, I'd recommend using a Swing Timer or SwingWorker to accomplish this, but those aren't the "requirements"

In order to render multiple objects, you need some way to store them, so you can update their states and renderer them. The simplest solution is a List, you can see Collections Trail for more details.

Now, if you also need to manage color, you can take a look at how I managed the deltas for each shape and should give you one idea for doing that

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private ReentrantLock shapesLock = new ReentrantLock();
        private List<Ellipse2D> shapes;

        public TestPane() {
            shapes = new ArrayList<>(25);
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    shapesLock.lock();
                    try {
                        shapes.add(new Ellipse2D.Double(e.getX() - 5, e.getY() - 5, 10, 10));
                    } finally {
                        shapesLock.unlock();
                    }
                }
            });

            Thread t = new Thread(new Runnable() {
                private Map<Shape, Double> deltas = new HashMap<>();

                @Override
                public void run() {
                    while (true) {
                        try {
                            shapesLock.lock();
                            try {
                                Rectangle containerBounds = getBounds();
                                containerBounds.setLocation(0, 0);
                                Iterator<Ellipse2D> it = shapes.iterator();
                                while (it.hasNext()) {
                                    Ellipse2D shape = it.next();
                                    Rectangle2D bounds = shape.getBounds2D();
                                    double y = bounds.getY();
                                    Double delta = deltas.get(shape);
                                    if (delta == null) {
                                        delta = 0d;
                                    }
                                    y += delta;
                                    shape.setFrame(bounds.getX(), y, bounds.getWidth(), bounds.getHeight());
                                    if (containerBounds.contains(shape.getBounds())) {
                                        delta = Math.min(delta + 0.25, 6d);
                                        deltas.put(shape, delta);
                                    } else {
                                        it.remove();
                                    }
                                }
                            } finally {
                                shapesLock.unlock();
                            }
                            repaint();
                            Thread.sleep(40);
                        }   catch (InterruptedException ex) {
                        }
                    }
                }
            });
            t.setDaemon(false);
            t.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            shapesLock.lock();
            try {
                for (Ellipse2D shape : shapes) {
                    g2d.fill(shape);
                }
            } finally {
                shapesLock.unlock();
            }
            g2d.dispose();
        }

    }

}

这篇关于如何生成多个圆圈的形状和动画这些形状下去框架的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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