【问题标题】:how to space out random circles across a JPanel when using an array使用数组时如何在JPanel上隔开随机圆圈
【发布时间】:2013-12-08 06:59:11
【问题描述】:

我正在尝试使用数组在 JPanel 上绘制 7 个随机圆圈。我设法让阵列工作,但现在我无法分隔圆圈。当我运行程序时,我看到绘制了多个圆圈,但它们都在同一个位置。所有的圆圈都有不同的大小和颜色。我遇到的另一个问题是让圆圈向屏幕底部移动。

public class keyExample extends JPanel implements ActionListener, KeyListener{

    private Circle[] circles = new Circle[7];

    Timer t = new Timer(5,this);
    //current x and y
    double x = 150, y = 200;
    double changeX = 0, changeY = 0;

    private int circlex = 0,circley = 0; // makes initial starting point of circles 0
    private javax.swing.Timer timer2;

    public keyExample(){
        t.start();
        addKeyListener(this);
        setFocusable(true);
        setFocusTraversalKeysEnabled(false);
        NewCircle();
        timer2 = new javax.swing.Timer(33,new MoveListener());
        timer2.start();
    }

    public void NewCircle(){
        Random colors = new Random();
        Color color = new Color(colors.nextInt(256),colors.nextInt(256),colors.nextInt(256));

        Random num= new Random();
        int radius = num.nextInt(45);

        for (int i = 0; i < circles.length; i++)
            circles[i] = new Circle(circlex,circley,radius,color);
        }
    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(Color.BLUE);
        g2.fill(new Rectangle2D.Double(x,y,40,40));
        for (int i = 0; i < circles.length; i++)
            circles[i].fill(g);
    }

    public void actionPerformed(ActionEvent e){
        repaint();
        x += changeX;
        y += changeY;
        changeX = 0;
        changeY = 0;
    }

    public void up() {
        if (y != 0){
            changeY = -3.5;
            changeX = 0;
        }
    }

    public void down() {
        if (y <= 350){
            changeY = 3.5;
            changeX = 0;
        }
    }

    public void left() {
        if (x >= 0) {
            changeX = -3.5;
            changeY = 0;
        }
    }

    public void right() {
        if (x <= 550) {
            changeX = 3.5;
            changeY = 0;
        }
    }

private class MoveListener implements ActionListener{

    public void actionPerformed(ActionEvent e){
        repaint();
        Random speed = new Random();
        int s = speed.nextInt(8);
        }
    }

    public void keyPressed(KeyEvent e){
        int code = e.getKeyCode();
        if (code == KeyEvent.VK_UP){
            up();
        }
        if (code == KeyEvent.VK_DOWN){
            down();
        }
        if (code == KeyEvent.VK_RIGHT){
            right();
        }
        if (code == KeyEvent.VK_LEFT){
            left();
        }
    }

    public void keyTyped(KeyEvent e) { }

    public void keyReleased(KeyEvent e) { }
}



Circle class


import java.awt.*;

public class Circle{

private int centerX, centerY, radius, coord;
private Color color;

public Circle(int x, int y, int r, Color c){
centerX = x;
centerY = y;
radius = r;
color = c;

}

public void draw(Graphics g){
Color oldColor = g.getColor();
g.setColor(color);
g.drawOval(centerX - radius, centerY - radius, radius * 2, radius * 2);
g.setColor(oldColor);

}

public void fill(Graphics g){
Color oldColor = g.getColor();
g.setColor(color);
g.fillOval(centerX - radius, centerY - radius, radius *2, radius * 2);
g.setColor(oldColor);
}

public boolean containsPoint(int x, int y){
int xSquared = (x - centerX) * (x - centerX);
int ySquared = (y - centerY) * (y - centerY);
int RadiusSquared = radius * radius;
return xSquared + ySquared - RadiusSquared <=0;
}



public void move(int xAmount, int yAmount){
centerX = centerX + xAmount;
centerY = centerY + yAmount;

}
}

【问题讨论】:

    标签: java swing jpanel keylistener paintcomponent


    【解决方案1】:

    这是依赖你不理解的借用代码的问题之一......

    基本上,您需要做的就是更改圈子的创建,例如...

    for (int i = 0; i < circles.length; i++) {
        circles[i] = new Circle(circlex, circley, radius, color);
        circlex += radius;
    }
    

    您可能希望重新考虑使用KeyListener,以支持Key Bindings,然后再发现KeyListener 无法按您预期的方式工作...

    出于某种奇怪的原因,您从MoveListeneractionPerfomed 方法中调用NewCirlces,这意味着这些圆圈只是在Timer 的每个触发器上重新创建...而不是, 在构造函数中先调用它

    您还在 paintComponent 方法中调用...这应该意味着圆圈永远不会移动,而是随机更改大小...

    更新了可运行的示例...

    我稍微修改了你的绘画代码NewCircleMoveListener...

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.geom.Rectangle2D;
    import java.util.Random;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class CircleExample extends JPanel implements ActionListener, KeyListener {
    
        public static void main(String[] args) {
            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 CircleExample());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        private Circle[] circles = new Circle[7];
    
        Timer t = new Timer(5, this);
        //current x and y
        double x = 150, y = 200;
        double changeX = 0, changeY = 0;
    
        private int circlex = 0, circley = 0; // makes initial starting point of circles 0
        private javax.swing.Timer timer2;
    
        public CircleExample() {
            NewCircle();
            t.start();
            addKeyListener(this);
            setFocusable(true);
            setFocusTraversalKeysEnabled(false);
            timer2 = new javax.swing.Timer(33, new MoveListener());
            timer2.start();
        }
    
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }
    
        public void NewCircle() {
            for (int i = 0; i < circles.length; i++) {
                Random colors = new Random();
                Color color = new Color(colors.nextInt(256), colors.nextInt(256), colors.nextInt(256));
    
                Random num = new Random();
                int radius = num.nextInt(90);
                circles[i] = new Circle(circlex, circley, radius, color);
                circlex += radius;
            }
        }
    
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g;
            g2.setColor(Color.BLUE);
            g2.fill(new Rectangle2D.Double(x, y, 40, 40));
            for (int i = 0; i < circles.length; i++) {
                circles[i].fill(g);
            }
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
            repaint();
            x += changeX;
            y += changeY;
            changeX = 0;
            changeY = 0;
        }
    
        public void up() {
            if (y != 0) {
                changeY = -3.5;
                changeX = 0;
            }
        }
    
        public void down() {
            if (y <= 350) {
                changeY = 3.5;
                changeX = 0;
            }
        }
    
        public void left() {
            if (x >= 0) {
                changeX = -3.5;
                changeY = 0;
            }
        }
    
        public void right() {
            if (x <= 550) {
                changeX = 3.5;
                changeY = 0;
    
            }
        }
    
        private class MoveListener implements ActionListener {
    
            @Override
            public void actionPerformed(ActionEvent e) {
                Random speed = new Random();
    
                for (Circle circle : circles) {
                    int s = speed.nextInt(8);
                    circle.move(0, s);
                }
                repaint();
            }
        }
    
        public void keyPressed(KeyEvent e) {
            int code = e.getKeyCode();
            if (code == KeyEvent.VK_UP) {
                up();
            }
            if (code == KeyEvent.VK_DOWN) {
                down();
            }
            if (code == KeyEvent.VK_RIGHT) {
                right();
            }
            if (code == KeyEvent.VK_LEFT) {
                left();
            }
        }
    
        public void keyTyped(KeyEvent e) {
        }
    
        public void keyReleased(KeyEvent e) {
        }
    
        public class Circle {
    
            private int centerX, centerY, radius, coord;
            private Color color;
    
            public Circle(int x, int y, int r, Color c) {
                centerX = x;
                centerY = y;
                radius = r;
                color = c;
    
            }
    
            public void draw(Graphics g) {
                Color oldColor = g.getColor();
                g.setColor(color);
                g.drawOval(centerX, centerY, radius, radius);
                g.setColor(oldColor);
    
            }
    
            public void fill(Graphics g) {
                Color oldColor = g.getColor();
                g.setColor(color);
                g.fillOval(centerX, centerY, radius, radius);
                g.setColor(oldColor);
            }
    
            public boolean containsPoint(int x, int y) {
                int xSquared = (x - centerX) * (x - centerX);
                int ySquared = (y - centerY) * (y - centerY);
                int RadiusSquared = radius * radius;
                return xSquared + ySquared - RadiusSquared <= 0;
            }
    
            public void move(int xAmount, int yAmount) {
                centerX = centerX + xAmount;
                centerY = centerY + yAmount;
    
            }
    
        }
    }
    

    【讨论】:

    • 我尝试了您在上面发布的代码,它有所帮助,但是当我运行该程序时,它继续在 JPanel 上绘制圆圈,直到 JPanel 上什么都没有。所以屏幕保持空白。 keylistener 类用于控制我在 JPanel 上绘制的矩形。
    • 1- 您是否删除了对NewCircle 的所有调用并在构造函数中放置了一个? 2- KeyListener 有严重的焦点问题,只需使组件具有焦点即可解决。与键盘交互的首选方式是通过 Key Bindings API; 3- 由于您从未将代码提供给Circle,我不能说您如何解决您的移动问题,但您需要提供move 方法,并了解它的区域的高度/宽度可以在里面移动,对于example
    • NewCircle 每次调用时都会创建所有圈子。所以基本上(如果你使用我的代码sn-p),基本上“看起来”的球就像它们已经移到屏幕右侧。它只需要在构造函数中调用一次即可初始化数组...
    • 可能是因为所有的圆都在同一个位置,而且是同一个半径...
    • 感谢代码工作,但如果你不介意帮助我做最后一件事。当圆圈到达屏幕底部时,是否可以让圆圈重新出现在屏幕顶部。因此,如果任何一个圆圈到达底部,该圆圈将返回到屏幕顶部
    猜你喜欢
    • 2013-12-25
    • 2018-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-28
    • 2012-11-21
    相关资源
    最近更新 更多