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

社会主义新天地 提交于 2019-12-11 18:13:13

问题


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

}

回答1:


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


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



回答2:


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.



来源:https://stackoverflow.com/questions/21336141/how-to-gui-using-paintcomponent-to-initialize-a-gui-and-then-to-add-gui-base

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