簡體   English   中英

JComponent上未顯示JComponents

[英]JComponents are not showing up on JPanel

由於某種原因,我的JComponents沒有出現在我的JPanel上。

這是我的代碼:

主班

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(我的主類)。

Main類中有一個JPanel,將其添加到JFrame中,然后該JPanel會同時添加這兩個JComponent,但是由於某種原因,即使我確定我已正確完成所有工作,JComponent也不會顯示。

如果有人知道為什么這行不通,那就太好了。 謝謝!

您的Food JComponent的首選大小將為0,0,這是它將優先選擇的大小。 一個簡單的解決方案是設置其首選大小或覆蓋其getPreferredSize()方法,但是我認為即使您這樣做,也可能會給程序帶來更大的問題。 我假設您要在同一屏幕空間中同時顯示蛇和食物。 如果是這樣,那么您的程序結構是錯誤的-食物和蛇類不應為組件類(例如,不應擴展JPanel或JComponent),而應為邏輯類。 您應該只使用一個JPanel進行繪制,該JPanel的paintComponent被覆蓋,並且在此方法內可以繪制蛇和食物。

附帶說明:您要重寫JFrame的paint方法,這是一件危險的事情。 幸運的是,您目前正在對其進行任何傷害,但是它的存在可能會在以后吸引您進入那里。 別。 我建議您刪除此方法和誘惑。 我自己的偏好是幾乎從不擴展JFrame,因為很少有理由這樣做,並且這樣做有風險。


關於您的評論:

明確地說,您是說我的Main中只有一個paintComponent()

我不知道您的“主要”是什么。 如上所述,我將創建一個JPanel進行繪畫,重寫其protected void paintComponent(Graphics g)方法,然后在此方法中繪畫Snake和Food。

而不是在我的Snake或Food課上?

正確。 Snake和Food不應擴展Swing組件,因此不應覆蓋paintComponent。 我給他們一個public void draw(Graphics g)方法,該方法在上述類的paintComponent方法中調用,並傳入JVM給定的Graphics或Graphics2D對象。

而且,我將使Main擴展為JPanel而不是JFrame。 如果是這樣,我該在Main類中的哪里創建Snake和Food對象?

這些細節將取決於您的實際代碼。 我相信您一定會解決的。

而且,我可以將keyListener保留在Snake類中還是應該將其放置在Main類中?

我幾乎從不使用KeyListeners,而是傾向於Key Bindings 看看我關於這個主題的許多文章 ,其中許多還包含示例代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM