paintComponent not working

不想你离开。 提交于 2019-12-08 04:39:10

问题


this may be a silly question but How do i call the paintComponent? Its not displaying the object at all. its within the, public class Ball extends JPanel implements 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();
                }
            }
        }
    }
}

回答1:


You should never call paintComponent (or paint) yourself. This is done by the RepaintManager.

The problem you're actually having is that fact speedx and speedy or 0, meaning you balls never move...

The other issue is that the ballAdder class is using a FlowLayout and you Ball class is not providing any details about it's preferred size, meaning that the Ball panel has a preferred size of 0x0.

Review

There is a significant issue with scalability with your design. Apart from the fact that you're going to find it difficult to add more then one ball to the UI because of layout issues...

Each Ball has it's own thread. This means, the more balls you add, the more threads that are going to be running. This is going to have a steady drain on resources and effect the performance of your application.

It would be better to provide a concept of a Drawable object which knew where it should be displayed within the concept it's container and could be painted from within the paintComponent. By utilising a single javax.swing.Timer it should be more capable of supporting a growing number of random balls.

First Fix

To fix you're first issue, you could do something like this...

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

The problem with this fix is that you're only ever going to be able to have a single Ball on the container, as it will want to occupy the maximum available space.

You might want to have a read through Using Layout Managers for more details

A (possible) better solution

A (possible) better solution would be to use a single JPanel as a "ball pit" which maintained a reference to list of balls.

You would then use the BallPitPane's paintComponent method to draw all the balls (in the balls list).

Through the use of a single javax.swing.Timer, you could iterate through the balls list and update there positions (within the context of the BallPitPane

IMHO, this easier then trying to fight with the layout managers or writing your own...

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);

        }        
    }    
}


来源:https://stackoverflow.com/questions/16908418/paintcomponent-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!