1

これはばかげた質問かもしれませんが、paintComponent を呼び出すにはどうすればよいですか? オブジェクトをまったく表示していません。その public クラス内で、Ball は JPanel を拡張し、Runnable を実装します。

public class Balls {

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

    public Balls() {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame("Balls!");
                frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
                frame.add(new ballAdder());
                frame.setSize(1000, 1000);
                frame.setVisible(true);

            }
        });
    }

    public class ballAdder extends JPanel {

        public ballAdder() {
            add(new Ball(5, 5));

        }
    }

    public class Ball extends JPanel implements Runnable {

        public int x, y;
        public int speedx, speedy;
        public int width = 40, height = 40;

        public Ball(int x, int y) {
            this.x = x;
            this.y = y;
            new Thread(this).start();

        }

        public void move() {
            x += speedx;
            y += speedy;
            if (0 > x || x > 950) {
                speedx = -speedx;
            }
            if (0 > y || y > 950) {
                speedy = -speedy;
            }
            repaint();
        }

        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.BLACK);
            g.fillOval(x, y, width, height);
        }

        public void run() {
            while (true) {
                move();
                try {
                    Thread.sleep(20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
4

1 に答える 1

4

自分自身に電話paintComponent(またはpaint) しないでください。これは によって行われますRepaintManager

あなたが実際に抱えている問題は、ボールが決して動かないという事実speedxspeedyまたはです...0

もう 1 つの問題は、ballAdderクラスが を使用してFlowLayoutおり、クラスがBall優先サイズに関する詳細を提供していないことです。つまり、Ballパネルの優先サイズは0x0です。

レビュー

設計のスケーラビリティに重大な問題があります。レイアウトの問題により、複数のボールを UI に追加するのが難しいという事実は別として...

それぞれBallに独自のスレッドがあります。これは、追加するボールが多いほど、実行されるスレッドが増えることを意味します。これにより、リソースが着実に消耗し、アプリケーションのパフォーマンスに影響を与えます。

Drawableコンテナの概念内のどこに表示されpaintedpaintComponent. シングルjavax.swing.Timerを利用することで、ますます多くのランダムボールをサポートできるようになります。

最初の修正

最初の問題を修正するには、次のようなことができます...

public class ballAdder extends JPanel {
    public ballAdder() {
        setLayout(new BorderLayout());
        add(new Ball(5, 5));
    }
}

Ballこの修正の問題は、利用可能な最大スペースを占有する必要があるため、コンテナーに1 つしか持てなくなることです。

詳細については、 Using Layout Managersをお読みください。

(可能な)より良い解決策

(可能な)より良い解決策はJPanel、ボールのリストへの参照を維持する「ボールピット」としてシングルを使用することです。

BallPitPane次に'sメソッドを使用してpaintComponent、(ボール リスト内の) すべてのボールを描画します。

単一の を使用することでjavax.swing.Timer、ボール リストを繰り返し処理し、その位置を更新できます (BallPitPane

私見、これはレイアウトマネージャーと戦ったり、独自のものを書いたりするよりも簡単です...

ここに画像の説明を入力

import java.awt.BorderLayout;
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.util.ArrayList;
import java.util.List;
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 Bounce {

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

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

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

    public class BallPitPane extends JPanel {

        private List<Ball> balls;
        private Random rand;

        public BallPitPane() {
            rand = new Random(System.currentTimeMillis());
            balls = new ArrayList<>(25);
            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (balls.isEmpty()) {
                        balls.add(new Ball(BallPitPane.this));
                    }

                    if (rand.nextBoolean()) {
                        balls.add(new Ball(BallPitPane.this));
                    }

                    for (Ball ball : balls) {
                        ball.move();
                    }
                    repaint();
                }
            });
            timer.start();
        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            for (Ball ball : balls) {
                ball.paint(g2d);
            }
            g2d.dispose();
        }
    }

    protected static int random(int min, int max) {

        return (int)Math.round(Math.random() * (max - min)) + min;

    }

    public static class Ball {

        public static final int WIDTH = 10;
        public static final int HEIGHT = 10;

        private int x;
        private int y;

        private int deltaX;
        private int deltaY;

        private Color color;
        private BallPitPane parent;

        public Ball(BallPitPane parent) {
            this.parent = parent;
            x = parent.getWidth() / 2;
            y = parent.getHeight() / 2;

            deltaX = random(-4, 4);
            deltaY = random(-4, 4);

            color = new Color(random(0, 255), random(0, 255), random(0, 255));
        }

        public void move() {
            x += deltaX;
            y += deltaY;

            if (x + WIDTH > parent.getWidth()) {
                x = parent.getWidth() - WIDTH;
                deltaX *= -1;
            } else if (x < 0) {
                x = 0;
                deltaX *= -1;
            }
            if (y + HEIGHT > parent.getHeight()) {
                y = parent.getHeight() - HEIGHT;
                deltaY *= -1;
            } else if (y < 0) {
                y = 0;
                deltaY *= -1;
            }
        }

        public Color getColor() {
            return color;
        }

        public void paint(Graphics2D g2d) {

            g2d.setColor(getColor());
            g2d.fillOval(x, y, WIDTH, HEIGHT);
            g2d.setColor(Color.BLACK);
            g2d.drawOval(x, y, WIDTH, HEIGHT);

        }        
    }    
}
于 2013-06-04T01:32:26.143 に答える