简体   繁体   English

Java将矩形添加到ArrayList中,然后绘制它们

[英]Java add rectangles to ArrayList and then draw them

I´m really in need of some help from you guys. 我真的很需要你们的帮助。 I try to add rectangles to an ArrayList and then loop through the list to draw them all. 我尝试将矩形添加到ArrayList中,然后遍历列表以绘制所有矩形。 I'm not sure if I'm using the right approach, but here is my code so far. 我不确定是否使用了正确的方法,但是到目前为止,这是我的代码。

Edit: the code does not draw the rectangles that I added to the ArrayList. 编辑:代码不会绘制我添加到ArrayList的矩形。 I don't even know if they are added the right way, or accessed through the for-loop in the right way. 我什至不知道是否以正确的方式添加它们,或者以正确的方式通过for循环访问它们。

In TestProgram 在TestProgram中

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.util.ArrayList;
import javax.swing.JFrame;


public class TestProgram extends JFrame {
    private ShapeRectangle rectangle;
    public ArrayList<Shapes> list = new ArrayList<Shapes>();


    public TestProgram(String title) {
        super(title);
        setLayout(new BorderLayout());
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        initComponents();
        setSize(500, 700);
        setVisible(true);
  }

    private void initComponents() {
        rectangle = new ShapeRectangle();    
        add(rectangle, BorderLayout.CENTER);

        list.add(rectangle);        
        Graphics g = getGraphics();
        for (int i = 0; i < list.size(); i++) {
            rectangle.draw(g);
        }
  }

    public static void main(String args[]) {
        new TestProgram("Drawing program");
    }
}

In class ShapeRectangles: 在ShapeRectangles类中:

import java.awt.Graphics;

public class ShapeRectangle extends Shapes {

    public ShapeRectangle() {}    

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponents(g);
        draw(g);        
    }

    @Override
    public void draw(Graphics g) {
       g.drawLine(20,20,60,60);
       g.drawLine(130,30,80,11);
       g.drawRect(200,30,20,140);        
   }
}

In class Shapes: 在Shapes类中:

import java.awt.Graphics;
import javax.swing.JPanel;

public abstract class Shapes extends JPanel {

    abstract public void draw(Graphics g); 

} }

Don't make Shapes a JPanel . 不要使Shapes成为JPanel Also take out its paintComponent method. 还要取出其paintComponent方法。

Instead have a JPanel class which is the main drawing surface. 而是有一个JPanel类,它是主绘图表面。 Keep the List<Shapes> in the class. List<Shapes>保留在类中。 Iterate through the list in the paintComponent method of that class, calling each Shapes 's draw method 遍历该类的paintComponent方法中的列表,调用每个Shapes的draw方法

class DrawingPanel extends JPanel {
    List<Shapes> shapes;
    // add shapes

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (Shapes shape: shapes) {
            shape.draw(g);
        }
    }
}

Then just add that panel to the frame. 然后只需将该面板添加到框架中即可。

Remember that all painting should be done with the Graphics context passed into the paintComponent method. 请记住,所有绘画都应通过传递到paintComponent方法中的Graphics上下文完成。 We do not do custom painting by using getGraphics . 我们不使用getGraphics进行自定义绘画。

Also you'll probably want to store some state in the Shapes class so you can change the x/y/width/height state. 另外,您可能需要在Shapes类中存储一些状态,以便可以更改x / y / width / height状态。 Right now you are are using the same hard coded values for all your shapes. 现在,您正在为所有形状使用相同的硬编码值。

abstract class Shapes {
    int x, y;
    public Shapes(int x, int y) {
        this.x = x; this.y = y;
    }
    protected abstract void draw(Graphics g);
}
class RectangleShape extends Shape {
    int width, height;
    public RectangleShape(int x, int y, int width, int height) {
        super(x, y);
        this.width = width; this.height = height;
    }
    @Override   
    public void draw(Graphics g) {
        g.fillRect(x, y, width, height);
    }
}

See a complete example with more complex objects with animation 查看带有动画的更复杂对象完整示例

This is bad, you either want to add it as a component with absolute positioning, or you want to draw it, choose one. 这很不好,您要么想要将其添加为具有绝对定位的组件,要么想要绘制它,请选择一个。

this.add(rectangle, BorderLayout.CENTER); // Add as component of the panel.
list.add(rectangle);                      // Add as method of drawing on the panel.

The latter will work better because you are drawing. 后者会更好,因为您正在绘图。 If you need drag-and-drop, add it as a child, but add the drawing to the child. 如果需要拖放,请将其作为子项添加,但将图形添加到子项中。

You can call repaint() on the JFrame to update the graphics after changing the rectangle's coordinates and sizes. 更改矩形的坐标和大小后,可以在JFrame上调用repaint()来更新图形。

DrawShapes 绘制形状

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class DrawShapes extends JFrame {
    public ArrayList<Shape> shapeList = new ArrayList<Shape>();

    public DrawShapes(String title) {
        super(title);

        this.setLayout(new BorderLayout());
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setSize(500, 700);
        this.setLocationRelativeTo(null);

        this.initComponents();
    }

    private void initComponents() {
        shapeList.add(new RectangleShape(20, 20, 60, 60));
        shapeList.add(new RectangleShape(130, 30, 80, 11));
        shapeList.add(new RectangleShape(200, 30, 20, 140));
    }

    @Override
    public void paint(Graphics g) {
        for (Shape s : shapeList) {
            s.draw(g);
        }
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                DrawShapes d = new DrawShapes("Drawing program");
                d.setVisible(true);
            }
        });
    }
}

RectangleShape 矩形形状

import java.awt.Graphics;

public class RectangleShape extends Shape {
    public RectangleShape(int x, int y, int width, int height) {
        super(x, y, width, height);
    }

    public RectangleShape() {
        super();
    }

    @Override
    public void draw(Graphics g) {
        g.drawRect(getX(), getY(), getWidth(), getHeight());
    }
}

Shape 形状

import java.awt.Graphics;

public abstract class Shape {
    private int x;
    private int y;
    private int width;
    private int height;

    public Shape() {
        this(0, 0, 1, 1);
    }

    public Shape(int x, int y, int width, int height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }

    public abstract void draw(Graphics g);

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }
}

Start by taking a look at the 2D Graphics , in particular Working with Geometry 首先看一下2D图形 ,特别是使用几何图形

The 2D Graphics API defines a Shape API which includes, amongst other things, a Rectangle class 2D图形API定义了Shape API,该API除其他外还包括Rectangle

For example... 例如...

在此处输入图片说明

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestRectangles {

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

    public TestRectangles() {
        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 List<Rectangle> rectangles;

        public TestPane() {
            rectangles = new ArrayList<>(25);
            Random ran = new Random();

            for (int index = 0; index < 10; index++) {
                int x = ran.nextInt(200 - 10);
                int y = ran.nextInt(200 - 10);
                int width = ran.nextInt(200 - x);
                int height = ran.nextInt(200 - y);
                rectangles.add(new Rectangle(
                        x, 
                        y, 
                        width, 
                        height));
            }
        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            for (Rectangle rect : rectangles) {
                g2d.draw(rect);
            }
            g2d.dispose();
        }

    }

}

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

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