Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
269 views
in Technique[技术] by (71.8m points)

java - How to GUI - Using paintcomponent() to initialize a GUI and then to add GUI based on mouse

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...