如何在Java中在运行时创建和绘制对象

如何在Java中在运行时创建和绘制对象,java,swing,graphics,paint,Java,Swing,Graphics,Paint,因此,我的目标是让连续的对象流从帧的右侧开始,在它们到达帧的左侧后消失/被删除。我将有一个球对象/图像,它将是静止的,但似乎向前移动,并跳过我希望创建的矩形对象。我希望在用户“存活”一段时间后停止创建对象 基本上,我的问题是如何加载JFrame,然后在运行时继续绘制对象。这样做一段时间,不断地绘制和移除对象。好的,这是一个非常基本的例子 基本上,它有两个Lists,一个是可用对象的“池”,另一个是当前屏幕上对象的List 其目的是减少需要创建的新对象的数量,而是保留一个可用对象池,主循环可以从中

因此,我的目标是让连续的对象流从帧的右侧开始,在它们到达帧的左侧后消失/被删除。我将有一个球对象/图像,它将是静止的,但似乎向前移动,并跳过我希望创建的矩形对象。我希望在用户“存活”一段时间后停止创建对象


基本上,我的问题是如何加载JFrame,然后在运行时继续绘制对象。这样做一段时间,不断地绘制和移除对象。

好的,这是一个非常基本的例子

基本上,它有两个
List
s,一个是可用对象的“池”,另一个是当前屏幕上对象的
List

其目的是减少需要创建的新对象的数量,而是保留一个可用对象池,主循环可以从中绘制。如果池为空且需要新对象,则将创建它,但一旦它离开屏幕,它将被替换到池中(假设我们需要它)

此示例使您能够动态更改活动对象的数量(25-10000)。系统将尝试平衡它在两个列表中管理的对象总数,使之精确到这个数量。如果你经常改变活动对象的数量,你可能会考虑允许池有一个“软糖”的因素,但是我会把它留给你。 还有一个增长率因子,这意味着当您在主循环的每个循环上增加活动对象的数量时,它将使可用对象的数量增加该数量,这有助于减少创建9000个新对象可能产生的延迟的可能性;)

导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.Font;
导入java.awt.FontMetrics;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Rectangle;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.util.ArrayList;
导入java.util.Iterator;
导入java.util.List;
导入java.util.Random;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JSlider;
导入javax.swing.Timer;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
导入javax.swing.event.ChangeEvent;
导入javax.swing.event.ChangeListener;
公开课考试{
公共静态void main(字符串[]args){
新测试();
}
公开考试(){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
例如printStackTrace();
}
JFrame=新JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(newtestpane());
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
});
}
公共类TestPane扩展了JPanel{
公共测试窗格(){
setLayout(新的BorderLayout());
GamePane GamePane=新建GamePane();
JSlider滑块=新JSlider(2510000);
添加(游戏窗格);
添加(滑块,BorderLayout.SOUTH);
slider.addChangeListener(新的ChangeListener(){
@凌驾
公共无效状态已更改(更改事件e){
gamePane.setActiveEntityCount(slider.getValue());
}
});
滑块设置值(25);
}
}
公共类游戏窗格扩展了JPanel{
私人实体名单;
私有实体;
私有int-activeCount;
私有整数增长率=100;
公共游戏窗格(){
实体池=新阵列列表(25);
activeEntities=新的ArrayList(25);
setFont(getFont().deriveFont(Font.BOLD,48f));
计时器计时器=新计时器(40,新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
Iterator it=activeEntities.Iterator();
while(it.hasNext()){
MovableEntity=it.next();
if(entity.update(getWidth(),getHeight())){
it.remove();
//如果对象总数超过activeCount,则此操作将删除对象
if(poolOfEntities.size()+activeEntities.size()import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

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 {

        public TestPane() {
            setLayout(new BorderLayout());
            GamePane gamePane = new GamePane();
            JSlider slider = new JSlider(25, 10000);
            add(gamePane);
            add(slider, BorderLayout.SOUTH);

            slider.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                    gamePane.setActiveEntityCount(slider.getValue());
                }
            });

            slider.setValue(25);
        }

    }

    public class GamePane extends JPanel {

        private List<MovableEntity> poolOfEntities;
        private List<MovableEntity> activeEntities;

        private int activeCount;

        private int growthRate = 100;

        public GamePane() {
            poolOfEntities = new ArrayList<>(25);
            activeEntities = new ArrayList<>(25);

            setFont(getFont().deriveFont(Font.BOLD, 48f));

            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {

                    Iterator<MovableEntity> it = activeEntities.iterator();
                    while (it.hasNext()) {

                        MovableEntity entity = it.next();
                        if (entity.update(getWidth(), getHeight())) {

                            it.remove();
                            // This drop objects if the total number of objects exceeds the activeCount
                            if (poolOfEntities.size() + activeEntities.size() < activeCount) {
                                poolOfEntities.add(entity);
                            }

                        }

                    }

                    for (int growth = 0; growth < growthRate && activeEntities.size() < activeCount; growth++) {

                        MovableEntity entity = null;
                        if (poolOfEntities.isEmpty()) {

                            entity = createNewEntity();

                        } else {

                            entity = poolOfEntities.remove(0);

                        }
                        activeEntities.add(entity);

                    }

                    repaint();

                }
            });
            timer.start();
        }

        protected MovableEntity createNewEntity() {

            int width = getWidth();
            int height = getHeight();
            if (width == 0) {
                width = getPreferredSize().width;
            } else if (height == 0) {
                height = getPreferredSize().height;
            }

            return new ShapeEntity(width, height);

        }

        public void setActiveEntityCount(int count) {

            if (count != activeCount) {

                activeCount = count;

            }

        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            Iterator<MovableEntity> it = activeEntities.iterator();
            while (it.hasNext()) {
                MovableEntity entity = it.next();
                entity.paint(g2d);
            }

            String text = Integer.toString(activeEntities.size());
            FontMetrics fm = g2d.getFontMetrics();
            int x = getWidth() - fm.stringWidth(text);
            int y = (getHeight() - fm.getHeight() )+ fm.getAscent();

            g2d.setColor(Color.WHITE);
            g2d.drawString(text, x, y);

            g2d.dispose();
        }

    }

    public interface Entity {

        public void paint(Graphics2D g);

    }

    public interface MovableEntity extends Entity {

        public boolean update(int width, int height);

    }

    public static class ShapeEntity implements MovableEntity {

        protected static final Color COLORS[] = {Color.BLACK, Color.BLUE, Color.CYAN, Color.DARK_GRAY, Color.GRAY, Color.GREEN, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.RED, Color.WHITE, Color.YELLOW};
        protected static final Random RND = new Random();

        private Rectangle bounds;
        private final Color color = COLORS[RND.nextInt(COLORS.length)];
        private int xDelta;

        public ShapeEntity(int width, int height) {

            reset(width, height);

        }

        protected void reset(int width, int height) {

            bounds = new Rectangle();

            bounds.width = 5 + RND.nextInt(25);
            bounds.height = 5 + RND.nextInt(25);

            bounds.x = -bounds.width; // offscreen
            bounds.y = RND.nextInt(height - bounds.height);

            xDelta = 1 + RND.nextInt(8);

        }

        @Override
        public boolean update(int width, int height) {

            boolean reset = false;
            bounds.x += xDelta;
            if (bounds.x > width) {
                reset(width, height);
                reset = true;
            }

            return reset;

        }

        @Override
        public void paint(Graphics2D g) {

            g.setColor(color);
            g.fill(bounds);

        }

    }

}