2016-11-17 59 views
0

由於某種原因,我的JComponents沒有顯示在我的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(); 
    } 
} 

SNAKE CLASS

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

主類中有一個JPanel被添加到JFrame中,然後JPanel添加了這兩個JComponents,但由於某種原因JComponents在執行時沒有顯示出來,儘管我很確定我有一切正確完成。

如果有人知道爲什麼這不起作用,那真棒。謝謝!

回答

3

你的食物JComponent的首選大小將是0,0,這是它將優先採用的大小。一個簡單的解決方案是設置其首選大小或覆蓋其方法,但我認爲即使您這樣做,您也可能會在程序中暴露出更大的問題。我假設你想要在同一屏幕空間中一起展示你的蛇和你的食物。如果是這樣,那麼你的程序結構是錯誤的 - 食物和蛇類不應該是組件類(例如,不應該擴展JPanel或JComponent),而應該是邏輯類。你應該只有一個用於繪製的JPanel,它的paintComponent被覆蓋,並且在這個方法裏面它繪製了你的蛇和食物。

一點點:你重載你的JFrame的繪畫方法,這是一個危險的事情。幸運的是,你現在對它有任何傷害,但它的存在可能會誘使你稍後在那裏吸引。別。我建議你刪除這種方法和誘惑。我自己的選擇是幾乎不會擴展JFrame,因爲很少有理由這樣做,並且可能會這樣做。


關於你的評論:

要清楚,你說只在我的主要

我不知道你的「主有一個的paintComponent() 「是。正如我上面提到的,我會創建一個用於繪畫的JPanel,覆蓋其protected void paintComponent(Graphics g)方法,然後在此方法中繪製Snake和Food。

而不是在我的蛇或食品類?

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

此外,我會讓我的Main擴展JPanel而不是JFrame。如果是這樣的話,我在哪裏創建我的主類中的蛇和食物對象?

這些細節將取決於您的實際代碼。我相信你會知道這一點。

而且,我可以讓keyListener保持在Snake類中,還是應該將它放在Main類中?

我幾乎從不使用KeyListeners,而是傾向於Key Bindings。看看我的many posts on this subject,其中很多都帶有更多示例代碼。

+0

謝謝你的回答!爲了說清楚,你說我的Main中只有一個paintComponent(),而不是在我的Snake或Food類中?而且,我將使用Main擴展JPanel而不是JFrame。如果是這樣的話,我在哪裏創建我的主類中的蛇和食物對象?而且,我可以將keyListener保留在Snake類中,還是應該將它放在Main類中? – Samkough

+1

@Samkough:看編輯 –

+0

好吧,非常感謝你這麼多人!我會嘗試單獨獨奏,看看它是如何發展的! – Samkough