简体   繁体   中英

JPanels don't appear in the JFame

I'm new to java. I do have a java class but I want to get ahead. I really like it! This is my problem. I'm trying to draw the two paddles needed for the game. I did create 2 objects for them, and they both "Show" but the following happens:

Main Runner

import javax.swing.JFrame;


public class PongRunner {

    public static void main (String[] args)
    {

        new PongRunner();
    }

    public PongRunner()
    {
        JFrame PongFrame= new JFrame();
        PongFrame.setSize(800,600);
        PongFrame.add(new PaddleB());
        PongFrame.add(new PaddleA());
        PongFrame.setLocationRelativeTo(null);
        PongFrame.setTitle("My Pong Game");
        PongFrame.setResizable(false);
        PongFrame.setVisible(true);
        PongFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

}

PaddleA and PaddleB are both drawRect Graphics and draw a specific rectangle.

The graphics that I tell JFrame to add first are the only ones visible. The one under it doesnt get added into the Frame I wanted to know why,and how i can draw both paddles in the same JFrame ... I'm reading my book and looking over the internet as much as possible, but no luck within these 2 days. Some help would be nice. I just started learning java and I think I'm making progress. Some tips would be nice too thanks :), specialy on actionListener since im going to have to use them to move the paddles!

SOURCE CODE OF BOTH PADDLES:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JPanel;
import javax.swing.Timer;

public class PaddleA extends JPanel implements ActionListener
{
    private Timer timer;

    public void timer()
    {
        timer = new Timer(25, this);
        timer.start();

    }

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

public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    g.setColor(Color.RED);
    g.fillRect(70,200,20,100);      
}
}

PaddleB:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JPanel;
import javax.swing.Timer;

public class PaddleB extends JPanel implements ActionListener
{

private Timer timer;

    public void timer()
    {
        timer = new Timer(25, this);
        timer.start();

    }

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


    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.setColor(Color.BLUE);
        g.fillRect(500, 200, 20, 100);

    }

}

As you've added the 2 paddles into the same BorderLayout.CENTER location of the main PongFrame , only the second paddle will be displayed.

This type of painting is more easily done using one Graphics object on one JComponent .

Swing components aren't really designed to be used like this. Each of your paddle JPanels is trying to paint a rectangle, but the container (the JFrame) and its layout manager will control the size and location of the JPanels. So the rectangle they paint may be outside their bounds, and won't appear at all.

Some Layout Managers will only show one of the JPanels if you add them one after another like this - see answer by Reimus .

To do animated graphics like this, you probably need to start with a single JComponent (eg a JPanel) that fills the JFrame, and paint both paddles as rectangles onto it.

This is because you add the first paddle and then add the second paddle over the first thus replacing them:

    PongFrame.add(new PaddleB());
    PongFrame.add(new PaddleA());

try using LayoutManager s here is just a quick sample:

    PongFrame.getContentPane().add(new PaddleB(),BorderLayout.WEST);
    PongFrame.getContentPane().add(new PaddleA(),BorderLayout.EAST);

also your g.fillRect(...); has x and y co-ordinates that are too large for the JFrame and thus are not displayed. Change it like so:

    g.fillRect(0,0, 20, 100);

Not related though:

  • dont use JFrame.add() rather JFrame.getContentPane().add()

UPADTE:

As others have mentioned the logic for the game is a bit off. You should have a single drawing panel which is added to the JFrame and all drawing is done on the single JPanel using Graphic s and not JPanel s. Here is a small example:

在此输入图像描述

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class PongRunner {

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

            @Override
            public void run() {
                new PongRunner();
            }
        });
    }

    public PongRunner() {
        JFrame PongFrame = new JFrame();
        PongFrame.setTitle("My Pong Game");
        PongFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        PongFrame.setResizable(false);
        PongFrame.setSize(400,400);
        //PongFrame.setLocationRelativeTo(null);
        PongFrame.getContentPane().add(new DrawingPanel());
        PongFrame.setVisible(true);
    }
}

class DrawingPanel extends JPanel {

    Rect rect1, rect2;

    public DrawingPanel() {
        super(true);
        rect1 = new Rect(80, 80, 20, 100, Color.yellow);
        rect2 = new Rect(100, 200, 20, 100, Color.red);

    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(rect1.getColor());
        g.fillRect(rect1.getX(), rect1.getY(), rect1.getWidth(), rect1.getHeight());
        g.setColor(rect2.getColor());
        g.fillRect(rect2.getX(), rect2.getY(), rect2.getWidth(), rect2.getHeight());
    }
}

class Rect {

    private Color color;
    private int x, y, height, width;

    Rect(int x, int y, int width, int height, Color color) {
        this.x = x;
        this.y = y;
        this.height = height;
        this.width = width;
        this.color = color;
    }

    public Color getColor() {
        return color;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return height;
    }

    public Rectangle getBounds() {
        return new Rectangle(x, y, width, height);
    }
}

Please note this snippet is not perfect and merely demonstrates the stereotypical logic needed for drawing rectangles to form a game of sorts

I don't have time to try running your code, but try setting the size and position of the "paddle" objects, or set them as non-opaque. I believe that Swing tries to speed up rendering by not drawing components which are completely covered by another opaque component. It may not be drawing one of your paddles for that reason.

If you do set the size and position of your paddles, you may have to modify your paintComponent methods: if my memory is correct, I think the Graphics object which is passed in is clipped to the area of the component, so 0,0 would be the top-left corner of the component.

you shouldn't add your JPanels to your JFrame by the JFrame#add(Component) method. Better add them to the contentPane: frame.getContentPane().add(panel); You should although read about LayoutManager s. They can help you by positining Components in your Frame or mess things up if you use them incorrect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM