简体   繁体   中英

JPanel not showing when added to another JPanel

I'm trying to create a game in Java - the game is going to be a 2-D scrolling game. I have a class called CornPanel which extends JPanel and shows a corn plant - the CornPanel 's are what will be moved across the screen. I know the CornPanel class is working because it shows up when I add it directly to a JFrame . However, when I try to add a CornPanel to another JPanel and then add that JPanel to the JFrame, the CornPanel doesn't show up.

Here's my CornPanel class (abbreviated - I took out the stuff I'm pretty sure isn't causing the problem):

package game;

import java.awt.Graphics;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;

public class CornPanel extends JPanel{

    BufferedImage cornImage;

    public CornPanel(){
        loadImages();
    }

    public void loadImages(){
        try{
            cornImage = ImageIO.read(new File("src\\cornBasic.png"));
        } catch(IOException e){
            e.printStackTrace();
        }
    }

    protected void paintComponent(Graphics g){
        g.drawImage(cornImage, 0, 0, cornImage.getWidth(), cornImage.getHeight(), this);
    }
}

My Game class:

package game;

import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JPanel;


public class Game extends JFrame{

    ArrayList<CornPanel> cornPanels;
    JPanel gameContainer;

    public Game(){
        cornPanels = new ArrayList<CornPanel>();
        gameContainer = new JPanel();
        setSize(1000, 1000);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBackground(new Color(98, 249, 255));
        setExtendedState(JFrame.MAXIMIZED_BOTH);
        getContentPane().add(gameContainer);

        addCornPanel();
        setVisible(true);
    }

    public void addCornPanel(){

        CornPanel cornPanel = new CornPanel();
        cornPanels.add(cornPanel);
        gameContainer.add(cornPanel);
        cornPanel.setVisible(true); 
        getContentPane().repaint();
        repaint();
    }


    public static void main(String[] args) {
        Game game = new Game();
    }
}

Note: I got it to work by setting the LayoutManager for both the JFrame and gameContainer to new GridLayout(1,1) , but the problem is that then I can't use setLocation() on the CornPanel in order to make it animate. If there's a way to do it without setLocation() let me know. Also, I took out a lot of code I don't think is necessary for diagnosing the problem - hopefully I didn't take out too much.

Your corn panel doesn't specify a prefered size, so the layout manager probably is just setting it to 0x0.

There is an easier way to add an icon into a pane. JLabel::JLabel(Icon) will create a label that has the image icon specified, and is of the right size to hold it.

If you do need something more complex than a single image, then your JComponent implementation should override getPreferredSize().

You also should call "pack" on your jframe, so that it can figure out the ideal size for display.

A few other comments not related to your original question:

  1. You shouldn't extend JFrame for the main frame, just create a new JFrame instance, and configure it.
  2. You should do the work in the Event Dispatch Thread. See EventQueue and more specifically read through Lesson: Concurrency in Swing

I know the CornPanel class is working because it shows up when I add it directly to a JFrame . However, when I try to add a CornPanel to another JPanel and then add that JPanel to the JFrame , the CornPanel doesn't show up.

The layout of the content pane of a frame is BorderLayout , the default constraint is CENTER which stretches a component to fill the space.

The default layout of a panel is FlowLayout which ..doesn't stretch the component to fit.

The best way to fix this is to (firstly) override the getPreferredSize() method of CornPanel to return a sensible size, then add it to a layout/constraint that has the behavior required when it has more space than it needs.

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