JComponent上未显示JComponents [英] JComponents are not showing up on JPanel

查看:151
本文介绍了JComponent上未显示JComponents的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于某种原因,我的JComponents没有显示在我的JPanel上.

My JComponents aren't showing up on my JPanel for some reason.

这是我的代码:

主要班级

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;

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

// Main Class - executes the game

public class Main extends JFrame
{
    public static int WIDTH = 800, HEIGHT = 800;
    private JPanel jp;
    private Dimension d;
    private Snake s;
    private Food f;

    public Main()
    {
        setTitle("Snake");
        setSize(WIDTH, HEIGHT);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        d = new Dimension(WIDTH, HEIGHT);
        jp = new JPanel();
        jp.setBackground(Color.GRAY);
        jp.setPreferredSize(d);
        getContentPane().add(jp);

        // adds the snake
        s = new Snake();
        jp.add(s);

        // adds food
        f = new Food();
        jp.add(f);
    }

    @Override
    public void paint(Graphics g)
    {
        super.paint(g);
        Graphics2D g2 = (Graphics2D) g;
    }

    public static void main(String args[])
    {
        new Main();
    }
}

蛇类

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;

import javax.swing.JComponent;

// Snake Class - creates the Snake object

public class Snake extends JComponent implements KeyListener
{
    public ArrayList snakeList = new ArrayList();
    public int snakeX, snakeY, snakeWidth, snakeHeight;

    public Snake()
    {
        snakeX = 100;
        snakeY = 100;
        snakeWidth = 20;
        snakeHeight = 20;

        snakeList.add(1);

        addKeyListener(this);
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;

        g2.setColor(Color.RED);
        g2.fillRect(snakeX, snakeY, snakeWidth, snakeHeight);
    }

    @Override
    public void keyPressed(KeyEvent e)
    {
        if(e.getKeyCode() == KeyEvent.VK_W || e.getKeyCode() == KeyEvent.VK_UP)
        {
            snakeX += 10;
            System.out.println("Up");
        }

        if(e.getKeyCode() == KeyEvent.VK_S || e.getKeyCode() == KeyEvent.VK_DOWN)
        {
            snakeX -= 10;
            System.out.println("Down");
        }

        if(e.getKeyCode() == KeyEvent.VK_D || e.getKeyCode() == KeyEvent.VK_RIGHT)
        {
            snakeY += 10;
            System.out.println("Right");
        }

        if(e.getKeyCode() == KeyEvent.VK_A || e.getKeyCode() == KeyEvent.VK_LEFT)
        {
            snakeY -= 10;
            System.out.println("Left");
        }
    }

    @Override
    public void keyReleased(KeyEvent e)
    {

    }

    @Override
    public void keyTyped(KeyEvent e)
    {}  
}

食品分类

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

import javax.swing.JComponent;
import javax.swing.JPanel;

// Food Class - the class that adds more Snake objects when collided with Snake

public class Food extends JComponent
{
    private Random r = new Random();
    public int foodX, foodY, foodWidth = 20, foodHeight = 20;

    public Food()
    {
        foodX = 400;
        foodY = 400;
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;

        g2.setColor(Color.YELLOW);
        g2.fillRect(foodX, foodY, foodWidth, foodHeight);
    }
}

如您所见,我有3个类:2个JComponents和1个JFrame(我的主类).

As you can see, I have 3 classes: 2 JComponents and 1 JFrame (my main class).

主类中有一个JPanel,将其添加到JFrame中,然后该JPanel会同时添加这两个JComponent,但是由于某种原因,即使我确定我已经拥有了所有东西,JComponent也不会在执行时显示正确完成.

The Main Class has a JPanel within it that is added to the JFrame, and then that JPanel adds both those two JComponents but for some reason the JComponents are not showing up when I execute even though I'm pretty sure I have everything done correctly.

如果有人知道为什么这行不通,那就太好了.谢谢!

If anyone knows why this is not working that'd be awesome. Thanks!

推荐答案

您的Food JComponent的首选大小将为0,0,这是它将优先选择的大小.一个简单的解决方案是设置其首选大小或覆盖其getPreferredSize()方法,但是我认为即使您执行此操作,也可能会给程序带来更大的问题.我假设您要在同一屏幕空间中同时显示蛇和食物.如果是这样,那么您的程序结构是错误的-食物和蛇类不应是组件类(例如,不应扩展JPanel或JComponent),而应是逻辑类.您应该只使用一个JPanel进行绘制,该JPanel的paintComponent被覆盖,并且在此方法内可以绘制蛇和食物.

Your Food JComponent's preferred size will be 0,0, and this is what size it will preferentially take. One simple solution is to either set its preferred size or override its getPreferredSize() method, but I think that even if you do this you might expose a bigger problem with your program. I assume that you want to display your snake and your food together in the same screen space. If so, then you're program structure is wrong -- food and snake classes should not be component classes (e.g., shouldn't extend JPanel or JComponent) but rather should be logical classes. You should have only one JPanel for drawing that has its paintComponent overridden and that inside this method it paints your snakes and food.

附带说明:您正在重写JFrame的paint方法,这是一件危险的事情.幸运的是,您目前对它造成了任何伤害,但是它的存在可能会在以后吸引您进入那里.别.我建议您删除此方法和诱惑.我自己的偏好是几乎从不扩展JFrame,因为这样做的理由很少,并且这样做有风险.

A side bit: you're overriding your JFrame's paint method, a dangerous thing to do. Fortunately you're doing any harm in it currently, but its presence might tempt you later to draw in there. Don't. I recommend that you remove this method and the temptation. My own preference is to almost never extend JFrame as there is rarely a reason to do this, and risks from doing so.

关于您的评论:

要明确地说,您是说我的Main中只有一个paintComponent()

To make clear, you're saying to only have one paintComponent() in my Main

我不知道您的主要"是什么.如上所述,我将创建一个JPanel进行绘画,重写其protected void paintComponent(Graphics g)方法,然后在此方法中绘制Snake和Food.

I don't know what your "Main" is. As I mentioned above, I would create one JPanel for painting, override its protected void paintComponent(Graphics g) method, and then paint the Snake and Food within this method.

而不是在我的Snake或Food类中?

and not in either my Snake or Food class?

正确. Snake和Food不应扩展Swing组件,因此不应覆盖paintComponent.我会给他们一个public void draw(Graphics g)方法,该方法在上述类的paintComponent方法中调用,并传入JVM给定的Graphics或Graphics2D对象.

Correct. Snake and Food should not extend a Swing component and therefore should not override paintComponent. I would give them a public void draw(Graphics g) method that is called in the above class's paintComponent method and that passes in the Graphics or Graphics2D object given from the JVM.

而且,我将使我的Main扩展JPanel而不是JFrame.如果是这种情况,我该在Main类中的哪里创建Snake和Food对象?

And also, I'll make my Main extend JPanel instead of JFrame. If that's the case, where do I create the Snake and Food Objects in my Main class?

这些细节将取决于您的实际代码.我相信您会解决这个问题.

These are details that will depend on your actual code. I'm confident that you'll figure this out.

而且,我可以将keyListener保留在Snake类中还是应该将其放置在Main类中?

And also, can I keep the keyListener in the Snake class or should I put it in the Main class?

我几乎从不使用KeyListeners,而是赞成按键绑定.看看我的关于该主题的许多帖子,其中许多带有示例代码.

I almost never use KeyListeners and instead favor Key Bindings. Look at my many posts on this subject, many with example code for more.

这篇关于JComponent上未显示JComponents的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆