0

Title says it all... My friend and I are doing this and we have no idea why Ball.java isn't actually making the balls in the gamePanel and then making the GUI. This is 8-ball pool, by the way. Here is the code:

Driver or Final2

import javax.swing.*; 
import java.awt.*; 
import java.io.*; 
import java.util.*; 
import java.awt.event.*; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.geom.Ellipse2D; 
import java.awt.geom.Rectangle2D;

public class Final2 implements ActionListener {
    JPanel titlePanel, gamePanel, buttonPanel;
    JLabel titleLabel, turnLabel, oneTypeLabel, twoTypeLabel;
    JButton newGameButton;
    int turn;
    String oneType,twoType;

    public JPanel createContentPane() {
        turn = 0;
        oneType = "";
        twoType = "";

        JPanel totalGUI = new JPanel();
        totalGUI.setLayout(null);

        titlePanel = new JPanel();
        titlePanel.setLayout(null);
        titlePanel.setLocation(10,0);
        titlePanel.setSize(500,100);
        totalGUI.add(titlePanel);
        titleLabel = new JLabel("8-ball Pool");
        titleLabel.setLocation(25,10);
        titleLabel.setSize(100,20);
        titleLabel.setHorizontalAlignment(0);
        titleLabel.setForeground(Color.red);
        titlePanel.add(titleLabel);
        gamePanel = new gamePanel();
        gamePanel.setLayout(null);
        gamePanel.setLocation(200,250);
        gamePanel.setSize(864,432); //this needs to be turned into 864x432 later
        gamePanel.setBorder(BorderFactory.createLineBorder(Color.black));
        totalGUI.add(gamePanel);

        buttonPanel = new JPanel();
        buttonPanel.setLayout(new FlowLayout());
        buttonPanel.setLocation(900,40);
        buttonPanel.setSize(200,40);
        totalGUI.add(buttonPanel);
        turnLabel = new JLabel("" + turn);
        turnLabel.setHorizontalAlignment(0);
        titlePanel.add(turnLabel);        
        oneTypeLabel = new JLabel(oneType);
        oneTypeLabel.setHorizontalAlignment(0);
        oneTypeLabel.setForeground(Color.red);
        buttonPanel.add(oneTypeLabel);
        twoTypeLabel = new JLabel(twoType);
        twoTypeLabel.setHorizontalAlignment(0);
        twoTypeLabel.setForeground(Color.blue);
        buttonPanel.add(twoTypeLabel);
        newGameButton = new JButton("New Game");
        newGameButton.addActionListener(this);
        buttonPanel.add(newGameButton);

        return totalGUI;
    }

    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == newGameButton) {
        }
    }

    public static void createAndShowGUI() {
        JFrame.setDefaultLookAndFeelDecorated(true);
        JFrame frame = new JFrame("8-ball Pool!");

        //Create and set up the content pane.
        Final gui = new Final();
        frame.setContentPane(gui.createContentPane());

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(1000, 1500);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                 createAndShowGUI();
                }
         });
    } }

gamePanel

import javax.swing.*; 
import java.awt.*; 
import java.io.*; 
import java.util.*; 
import java.awt.event.*; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import  java.awt.geom.Ellipse2D; 
import java.awt.geom.Rectangle2D;

public class gamePanel extends JPanel {
    private boolean setup = true;

    public gamePanel() {    setOpaque(true);    setBackground(Color.GREEN);  
    }
    public void paintComponent(Graphics g) {    /*  Graphics2D g2 = (Graphics2D) g;     Ellipse2D circle = new Ellipse2D.Double(100 - 18,100
-18,18,18);     g2.setColor(Color.BLUE);    g2.draw(circle);    Rectangle2D rect = new Rectangle2D.Double(100 - 18,100 -5,18,5);
    g2.setColor(Color.WHITE);   g2.draw(rect); */
    super.paintComponent(g);    //column 1  //1     /*
    g.setColor(Color.BLACK);    g.drawOval(624,206,20,20);
    g.setColor(Color.YELLOW);   g.fillOval(625,207,18,18);

    //column 2  //14    g.setColor(Color.BLACK);        
    g.drawOval(644,196,20,20);  g.setColor(Color.GREEN);
    g.fillOval(645,197,18,18);

    //4     g.setColor(Color.BLACK);    g.drawOval(644,216,20,20);
    g.setColor(Color.MAGENTA);  g.fillOval(645,217,18,18);
    g.setColor(Color.WHITE);    g.fillRect(645 + 7,217,5,18);

    //column 3  //5     g.setColor(Color.BLACK);    g.drawOval(664,186,20,20);
    g.setColor(Color.ORANGE.darker());  g.fillOval(665,187,18,18);
    g.setColor(Color.WHITE);    g.fillRect(665 + 7,187,5,18);

    //8     g.setColor(Color.BLACK);    g.drawOval(664,206,20,20);
    g.setColor(Color.BLACK);    g.fillOval(665,207,18,18);

    //13    g.setColor(Color.BLACK);    g.drawOval(664,226,20,20);
    g.setColor(Color.ORANGE.darker());  g.fillOval(665,227,18,18);

    //column 4  //11    g.setColor(Color.BLACK);
    g.drawOval(684,176,20,20);  g.setColor(Color.RED);
    g.fillOval(685,177,18,18);  g.setColor(Color.WHITE);    g.fillRect(685
+ 7,177,5,18);

    //2     g.setColor(Color.BLACK);            g.drawOval(684,196,20,20);
    g.setColor(Color.BLUE);     g.fillOval(685,197,18,18);

    //12    g.setColor(Color.BLACK);            g.drawOval(684,216,20,20);
    g.setColor(Color.MAGENTA);  g.fillOval(685,217,18,18);

    //9 (looks suspiciously like solid yellow)  g.setColor(Color.BLACK);
    g.drawOval(684,236,20,20);  g.setColor(Color.YELLOW);
    g.fillOval(685,237,18,18);  g.setColor(Color.WHITE);    g.fillRect(685
+ 7,237,5,18);

    //column 5  //7     g.setColor(Color.BLACK);        
    g.drawOval(704,166,20,20);
    g.setColor(Color.ORANGE.darker().darker().darker().darker());
    g.fillOval(705,167,18,18);

    //10    g.setColor(Color.BLACK);    g.drawOval(704,186,20,20);
    g.setColor(Color.BLUE);     g.fillOval(705,187,18,18);
    g.setColor(Color.WHITE);    g.fillRect(705 + 7,187,5,18);

    //15    g.setColor(Color.BLACK);    g.drawOval(704,206,20,20);
    g.setColor(Color.ORANGE.darker().darker().darker().darker());
    g.fillOval(705,207,18,18);  g.setColor(Color.WHITE);    g.fillRect(705
+ 7,207,5,18);

    //3     g.setColor(Color.BLACK);    g.drawOval(704,226,20,20);
    g.setColor(Color.RED);  g.fillOval(705,227,18,18);

    //6     g.setColor(Color.BLACK);    g.drawOval(704,246,20,20);
    g.setColor(Color.GREEN);    g.fillOval(705,247,18,18);
    g.setColor(Color.WHITE);    g.fillRect(705 + 7,247,5,18);

    //the almighty cue ball     g.setColor(Color.BLACK);
    g.drawOval(304,206,20,20);  g.setColor(Color.WHITE);
    g.fillOval(305,207,18,18);  */  if (setup) {
        setup = false;
        //column 1
        //1
        Ball ball1 = new Ball(1,624,206);
        this.add(ball1);
        this.update(this.getGraphics()); //this breaks everything yay

        //column 2
        //6
        Ball ball6 = new Ball(6,644,196);
        //12
        Ball ball12 = new Ball(12,644,216);

        //column 3
        //13
        Ball ball13 = new Ball(13,664,186);
        //8
        Ball ball8 = new Ball(8,664,206);
        //5
        Ball ball5 = new Ball(5,664,226);

        //column 4
        //11
        Ball ball11 = new Ball(11,684,176);
        //2
        Ball ball2 = new Ball(2,684,196);
        //4
        Ball ball4 = new Ball(4,684,216);   }
    } }

Ball

import javax.swing.*; 
import java.awt.*; 
import java.io.*; 
import java.util.*; 
import java.awt.event.*; 
import java.awt.Color;

public class Ball extends gamePanel {
    private int xcor,ycor;
    private int rxcor,rycor,radius;
    private int num;

    public Ball(int n,int x,int y) {
        num = n;
        xcor = x;
        ycor = y;
        radius = 9;
        this.setVisible(true);

    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        boolean isStriped = (num 8);
        int color = num%8;

        if (color == 0) {
         if (isStriped) {
                //8ball
                g.setColor(Color.BLACK);
                g.drawOval(xcor,ycor,20,20);
                g.setColor(Color.BLACK);
                g.fillOval(xcor+1,ycor+1,18,18);
         }
         else {
                //cue ball is 16
                g.setColor(Color.BLACK);
                g.drawOval(xcor,ycor,20,20);
                g.setColor(Color.WHITE);
                g.fillOval(xcor+1,ycor+1,18,18);
         }        
        }        
        else {
         if (color == 1) {
                if (isStriped) {
                 //9ball
                 g.setColor(Color.BLACK);
                 g.drawOval(xcor,ycor,20,20);
                 g.setColor(Color.WHITE);
                 g.fillOval(xcor+1,ycor+1,18,18);
                 g.setColor(Color.YELLOW);
                 g.fillOval(xcor+8,ycor+1,5,18);
                }
                else {
                 //1ball
                 g.setColor(Color.BLACK);
                 g.drawOval(xcor,ycor,20,20);
                 g.setColor(Color.YELLOW);
                 g.fillOval(xcor+1,ycor+1,18,18);
                }
         }
         else {
                if (color == 2) {
                 if (isStriped) {
                        //10ball
                        g.setColor(Color.BLACK);
                        g.drawOval(xcor,ycor,20,20);
                        g.setColor(Color.WHITE);
                        g.fillOval(xcor+1,ycor+1,18,18);
                        g.setColor(Color.BLUE);
                        g.fillOval(xcor+8,ycor+1,5,18);
                 }
                 else {
                        //2ball
                        g.setColor(Color.BLACK);
                        g.drawOval(xcor,ycor,20,20);
                        g.setColor(Color.BLUE);
                        g.fillOval(xcor+1,ycor+1,18,18);
                 }
                }
                else {
                 if (color == 3) {
                        if (isStriped) {
                         //11ball
                         g.setColor(Color.BLACK);
                         g.drawOval(xcor,ycor,20,20);
                         g.setColor(Color.WHITE);
                         g.fillOval(xcor+1,ycor+1,18,18);
                         g.setColor(Color.RED);
                         g.fillOval(xcor+8,ycor+1,5,18);
                        }
                        else {
                         //3ball
                         g.setColor(Color.BLACK);
                         g.drawOval(xcor,ycor,20,20);
                         g.setColor(Color.RED);
                         g.fillOval(xcor+1,ycor+1,18,18);
                        }
                 }
                 else{
                        if (color == 4) {
                         if (isStriped) {
                                //12ball
                                g.setColor(Color.BLACK);
                                g.drawOval(xcor,ycor,20,20);
                                g.setColor(Color.WHITE);
                                g.fillOval(xcor+1,ycor+1,18,18);
                                g.setColor(Color.MAGENTA);
                                g.fillRect(xcor+8,ycor+1,5,18);
                         }
                         else {
                                //4ball
                                g.setColor(Color.BLACK);
                                g.drawOval(xcor,ycor,20,20);
                                g.setColor(Color.MAGENTA);
                                g.fillRect(xcor+1,ycor+1,18,18);
                         }
                        }
                        else {
                         if (color == 5) {
                                if (isStriped) {
                                 //13ball
                                 g.setColor(Color.BLACK);
                                 g.drawOval(xcor,ycor,20,20);
                                 g.setColor(Color.WHITE);
                                 g.fillOval(xcor+1,ycor+1,18,18);
                                 g.setColor(Color.ORANGE.darker());
                                 g.fillRect(xcor+8,ycor+1,5,18);
                                }
                                else {
                                 //5ball
                                 g.setColor(Color.BLACK);
                                 g.drawOval(xcor,ycor,20,20);
                                 g.setColor(Color.ORANGE.darker());
                                 g.fillOval(xcor+1,ycor+1,18,18);
                                }
                         }
                         else {
                                if (color == 6) {
                                 if (isStriped) {
                                        //14ball
                                        g.setColor(Color.BLACK);
                                        g.drawOval(xcor,ycor,20,20);
                                        g.setColor(Color.WHITE);
                                        g.fillOval(xcor+1,ycor+1,18,18);
                                        g.setColor(Color.GREEN);
                                        g.fillOval(xcor+8,ycor+1,5,18);
                                 }
                                 else {
                                        //6ball
                                        g.setColor(Color.BLACK);
                                        g.drawOval(xcor,ycor,20,20);
                                        g.setColor(Color.GREEN);
                                        g.fillOval(xcor+1,ycor+1,18,18);
                                 }
                                }
                                else {
                                 if (color == 7) {
                                        if (isStriped) {
                                         //15ball
                                         g.setColor(Color.BLACK);
                                         g.drawOval(xcor,ycor,20,20);
                                         g.setColor(Color.WHITE);
                                         g.fillOval(xcor+1,ycor+1,18,18);
                                         g.setColor(Color.ORANGE.darker().darker().darker().darker());
                                         g.fillOval(xcor+8,ycor+1,5,18);
                                        }
                                        else {
                                         //7ball
                                         g.setColor(Color.BLACK);
                                         g.drawOval(xcor,ycor,20,20);
                                         g.setColor(Color.ORANGE.darker().darker().darker().darker());
                                         g.fillOval(xcor+1,ycor+1,18,18);
                                        }
                                 }
                                }
                         }
                        }
                 }
                }
         }
        }
    }

}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
StevenZ
  • 3
  • 1
  • Heck lot of code! Do you really want we debug that code for you? – dic19 Jan 24 '14 at 15:19
  • 1
    Please, at the very least, make sure your code in the question is readable easily... it is not well formatted. – Jonathan Drapeau Jan 24 '14 at 15:27
  • Don't mix code formatting an quoted text. Use code formatting for code, input/output & structured documents like HTML or XML. To do that, select the sample and click the `{}` button above the messaged posting/editing form. – Andrew Thompson Jan 24 '14 at 15:55
  • 1
    See how much better it looks now? It was a mess. I hope I've convinced you, since I don't do that for people often. – Andrew Thompson Jan 24 '14 at 16:02

2 Answers2

3

Here's the thing. You don't want a bunch of JPanels as balls. You should just have one JPanel to paint on and use only that one paintComponent method for all the Balls. So you Ball class doesn't need to extend anything at all. The Ball class should only be a model to hold data, such ass the RGB color. You should also a draw method in the ball class that take a Graphics object as an argument, and draws the ball

public class Ball {
    int R, G, B;
    boolean striped;
    int x, y;

    public Ball(int R, int G, int B, boolean striped) {
        this.R = R:
        this.G = G;
        this.B = B;
        this.striped = striped;
    }

    public void drawBall(Graphics g) {
        if (isStriped) {
            // draw the ball with the values from this class
        }
        else {
            // draw the ball with the values from this class
        } 
    }
}

Then in the class that you're doing the actual drawing with, you want to have a list of Ball objects

public class TablePanel extends JPanel {
    List<Ball> balls = new ArrayList<Ball>();

    public TablePanel(){
        makeBalls();
    }

    public void makeBalls(){
        balls.add(new Ball(213, 2, 255, true);
        // add more balls
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        for (Ball ball : balls) {
            ball.drawBall(g);
        }
    }
}

You can see all I did was use the method ball.drawBall(g);. The ball will appear. But you will also need to specify the x and y location of the ball too. Then when you need to animate the balls, just change their x and y fields.

Here's an example

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class SorryPoolTable extends JPanel{

    List<ABall> balls = new ArrayList<ABall>();

    public SorryPoolTable(){
        makeBalls();
    }

    public void makeBalls(){
        balls.add(new ABall(213, 2, 255, true, 125, 25));
        balls.add(new ABall(65, 34, 25, true, 150, 135));
        balls.add(new ABall(124, 211, 45, true, 160, 180));
        balls.add(new ABall(35, 123, 255, true, 200, 200));
        balls.add(new ABall(45, 222, 255, true, 50, 200));
        balls.add(new ABall(65, 92, 155, true, 125, 175));

    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        for (ABall ball : balls) {
            ball.drawBall(g);
        }
    }

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

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                JFrame frame = new JFrame("Sorry Pool Table");
                frame.add(new SorryPoolTable());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

class ABall {
    int R, G, B;
    boolean striped;
    int x, y;

    public ABall(int R, int G, int B, boolean striped, int x, int y) {
        this.R = R;
        this.G = G;
        this.B = B;
        this.striped = striped;
        this.x = x;
        this.y = y;
    }

    public void drawBall(Graphics g) {
        g.setColor(new Color(R, G, B));
        g.fillOval(x, y, 20, 20);
    }
}

enter image description here


UPDATE

Example of MouseMotionListener. This is a very simple example. The stick doesn't rotate or anthing. Take a look at Graphics2D tutorial for more complex details about how you can accomplish this

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


public class PoolStick extends JPanel{
    int x = 100;
    int y = 100;

    public PoolStick() {
        addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseMoved(MouseEvent e) {
                Point p = e.getPoint();
                x = (int)p.getX();
                y = (int)p.getY();
                repaint();
            }
        });
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.fillRect(x, y, 5, 200);
    }

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

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                JFrame frame = new JFrame("Sorry Pool Table");
                frame.add(new PoolStick());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • Ok, thanks! ALso, how do I make a rectangle that follows the mouse around, something along the lines of a custom cursor that represents the stick in pool. I understand how to initialize GUI, but how do I make it so everytime I move my mouse a rectangle follows my mouse? – StevenZ Jan 24 '14 at 16:14
  • You need a `MouseMotionListener` and @Override the `mouseMoved` method. get the cursor location with `e.getPoint();` and `reapaint() with new `x` `y` cordinates – Paul Samsotha Jan 24 '14 at 16:23
1

I think you have two problems here:

  1. You don't override paintComponent() properly. This is a protected method, not public. If you add @Override annotation on this method then the compiler will complain. This is a really good reason for adding this annotation every time you need to override some method.

  2. Ball class extends from gamePanel so when you call super.paintComponent(g) in the first class it will call paintComponent(g) on its ancestor. If you add balls inside gamePanel then you'll get an endless loop that will probably cause a stack overflow.

Off-topic

Always follow Java Code Conventions.

dic19
  • 17,821
  • 6
  • 40
  • 69
  • The compiler will _not_ complain about `public` or `protected` with `paintComponent`. You can override with a higher visibility but not a lower one. `public` is higher than `protected` so there's no problem – Paul Samsotha Jan 24 '14 at 15:57
  • @peeskillet Noted! But in this case is not good at all make `paintComponent()` public, is it? – dic19 Jan 24 '14 at 16:41