2

In my code I am trying to paint by JFrame but it is not painting correctly. I tell the frame to paint in the beginning where I create it however it is the normal grey color once it is created. I think it may have to do with the fact that I am repainting it, if so how can I make sure it is repainted yellow? Could someone try to figure out why my code is not painting the JFrame Yellow? Thank you!

public class EvolutionColor {

    public static void main(String args[]) {
        JFrame frame = new JFrame("Bouncing Ball");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        BallPanel bp = new BallPanel();
        frame.add(bp);
        frame.setSize(600, 600); // set frame size
        frame.setVisible(true); // display frame
        frame.setBackground(Color.YELLOW);
    }

    class BallPanel extends JPanel implements ActionListener {

        private int delay = 10;
        protected Timer timer;

        private int x = 0;        // x position
        private int y = 0;        // y position
        private int radius = 15;  // ball radius

        private int dx = 2;       // increment amount (x coord)
        private int dy = 2;       // increment amount (y coord)

        public BallPanel() {
            timer = new Timer(delay, this);
            timer.start();       // start the timer
        }

        public void actionPerformed(ActionEvent e) {
            repaint();
        }

        public void paintComponent(Graphics g) {
            super.paintComponent(g); // call superclass's paintComponent 
            g.setColor(Color.red);

// check for boundaries
            if (x < radius) {
                dx = Math.abs(dx);
            }
            if (x > getWidth() - radius) {
                dx = -Math.abs(dx);
            }
            if (y < radius) {
                dy = Math.abs(dy);
            }
            if (y > getHeight() - radius) {
                dy = -Math.abs(dy);
            }

// adjust ball position
            x += dx;
            y += dy;
            g.fillOval(x - radius, y - radius, radius * 2, radius * 2);
        }


}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
user3474775
  • 199
  • 1
  • 2
  • 12
  • Aside: I would create a `Ball` class to hold the state of a ball object and have a method to manipulate it and draw it, inside the `Ball` class. This makes it more maintainable if you want to have more than just one ball. See example [here](http://stackoverflow.com/a/22283611/2587435). Also have a look at [Initial Threads](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html). Swing apps should be run on the EDT – Paul Samsotha May 30 '14 at 03:06

2 Answers2

4

Don't set the JFrame to yellow, set the BallPanel object to yellow.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • @user3474775: glad it's working, but I too strongly agree with MadProgrammer -- your paintComponent method should have no program logic within it since you do not have full control over when or even if it gets called. The logic should be in the Timer, and the paintComponent method should be for painting and painting only. – Hovercraft Full Of Eels May 30 '14 at 02:45
3

Make BallPanel transparent...

bp.setOpaque(false);

Don't make decisions about the state of your component within paintComponent method, these decisions should be made within you actionPerformed method

Painting is for painting and paintComponent may be called for any number of reasons, many which you don't control

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366