简体   繁体   English

如何在JPanel中移动多个对象

[英]how to move multiple objects in JPanel

I want to create multiple squares that move independently and at the same time,and I think the most efficient way is through the transform method in Graphics2D,but I'm not sure how to make it work for each square.I want the square object to be self contained and create its own transforms(instance transforms). 我想创建多个独立且同时移动的正方形,我认为最有效的方法是通过Graphics2D中的transform方法,但是我不确定如何使它适用于每个正方形。我想要正方形对象成为独立的并创建自己的转换(实例转换)。 Here's what I have so far. 到目前为止,这就是我所拥有的。

TransformPanel 转换面板

import javax.swing.*; 
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.util.Random;
import java.util.concurrent.TimeUnit;

public class TranformPanel extends JPanel {
    private int[] xcoords = {250,248,253,255,249}; 
    private int[] ycoords = {250,253,249,245,250}; 
    private double randomx = 0; 
    private double randomy = 0;
    public void paintComponent(Graphics g) 
    { 
        super.paintComponent(g); 
        drawTransform(g,randomx,randomy);
    } 
    private void drawTransform(Graphics g,double randomx,double randomy) 
    {  
        Random rn = new Random(); 
        int xnum = rn.nextInt(10)-5; 
        randomx = xnum; 
        int ynum = rn.nextInt(10)-5; 
        randomy = ynum;

        Rectangle rect = new Rectangle(250,250,10,10);  
        AffineTransform transform = new AffineTransform();   
        Graphics2D g2d = (Graphics2D)g;   

        transform.translate(randomx,randomy);
        g2d.draw(transform.createTransformedShape(rect));  

        }
    }

TransformDraw 变换绘图

import java.awt.*; 
import javax.swing.*; 
import java.awt.geom.AffineTransform;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;

public class TransformDraw{ 
    private static TranformPanel panel = new TranformPanel();
    public static void main(String[] args) {    
        // Setup our JFrame details 
        JFrame frame = new JFrame();
        frame.setTitle("Transform Polygon Example");
        frame.setSize(500,500);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());   
        frame.setVisible(true);
        frame.add(panel); 
        Scanner input = new Scanner(System.in); 
        for (int i=0;i<10;i++) 
        { 
        try {
            TimeUnit.SECONDS.sleep(1);
            frame.repaint(); 
        } catch (InterruptedException e) {
            e.printStackTrace();
            }
        } 
    } 
}

Thanks is Advance! 谢谢前进!

Start by creating something that can manage it's location (and other properties) and which can be "painted" 首先创建可以管理其位置(和其他属性)并且可以“绘制”的对象

public interface Box {
    public void update(Dimension size);
    public void paint(Graphics2D g2d);
}

So, this is pretty basic, all it can do is be updated (within a given area) and be painted. 因此,这非常基础,它所能做的就是在给定区域内进行更新和绘制。 You could expose other properties (like it's bounding box for example) based on your particular needs 您可以根据自己的特定需求公开其他属性(例如,它的边界框)

Next, we need a simple implementation, something like... 接下来,我们需要一个简单的实现,例如...

public class DefaultBox implements Box {

    private Color color;
    private Rectangle bounds;

    private int xDelta;
    private int yDelta;

    public DefaultBox(Color color, Dimension size) {
        this.color = color;
        bounds = new Rectangle(new Point(0, 0), size);

        xDelta = 1 + (int) (Math.random() * 10);
        yDelta = 1 + (int) (Math.random() * 10);
    }

    @Override
    public void update(Dimension size) {
        bounds.x += xDelta;
        bounds.y += yDelta;

        if (bounds.x < 0) {
            bounds.x = 0;
            xDelta *= -1;
        } else if (bounds.x + bounds.width > size.width) {
            bounds.x = size.width - bounds.width;
            xDelta *= -1;
        }
        if (bounds.y < 0) {
            bounds.y = 0;
            yDelta *= -1;
        } else if (bounds.y + bounds.height > size.height) {
            bounds.y = size.height - bounds.height;
            yDelta *= -1;
        }
    }

    @Override
    public void paint(Graphics2D g2d) {
        g2d.setColor(color);
        g2d.fill(bounds);
    }

}

Now, this maintains a simple Rectangle instance, which describes the location and size of the object, it also maintains properties about the color and it's speed. 现在,它维护了一个简单的Rectangle实例,该实例描述了对象的位置和大小,还维护了有关颜色及其速度的属性。

When update is called, it updates it's location and does some simple bounds checking to make sure that the box remains within the specified area. 调用update ,它会更新其位置并进行一些简单的边界检查,以确保该框保持在指定区域内。

When paint is called, it simply paints itself. 调用paint ,它只是自己绘制。

Finally, we need some way to update and paint these boxes.... 最后,我们需要某种方式来更新和绘制这些框。

public class TestPane extends JPanel {

    private List<Box> boxes;
    private Color[] colors = {Color.RED, Color.BLACK, Color.BLUE, Color.CYAN, Color.DARK_GRAY, Color.GREEN, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.WHITE, Color.YELLOW};

    public TestPane() {
        boxes = new ArrayList<>(25);
        for (int index = 0; index < 100; index++) {
            Color color = colors[(int) (Math.random() * colors.length)];
            int width = 10 + (int) (Math.random() * 9);
            int height = 10 + (int) (Math.random() * 9);
            boxes.add(new DefaultBox(color, new Dimension(width, height)));
        }

        Timer timer = new Timer(40, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                for (Box box : boxes) {
                    box.update(getSize());
                }
                repaint();
            }
        });
        timer.start();
    }

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

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (Box box : boxes) {
            Graphics2D g2d = (Graphics2D) g.create();
            box.paint(g2d);
            g2d.dispose();
        }
    }

}

Okay, so again, this is pretty simple. 好的,再说一次,这很简单。 It maintains a List of Box 's, a Swing Timer to periodically update the List of Box 's, calling their update method. 它维护一个Box List ,一个Swing Timer用于定期更新Box List ,并调用其update方法。 The Timer the simply calls repaint , which (in a round about way) ends up calling paintComponent , which then just calls paint on each instance of Box . Timer简单地调用repaint ,最终(以某种方式)最终调用paintComponent ,然后再对Box每个实例调用paint

100 boxes... 100盒...

100盒

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

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