2016-11-17 3 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 КЛАСС

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) 
    {} 
} 

FOOD КЛАСС

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, и это то, что он предпочитает. Одно простое решение - либо установить его предпочтительный размер, либо переопределить его метод getPreferredSize(), но я думаю, что даже если вы это сделаете, вы можете столкнуться с большей проблемой в своей программе. Я предполагаю, что вы хотите отобразить свою змею и свою пищу вместе в одном и том же пространстве экрана. Если это так, то у вас неправильная структура программы - классы продуктов питания и змей не должны быть составными классами (например, не должны расширять 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 выше класса и проходит через объект Graphics или Graphics2D, указанный в JVM.

А также, я сделаю свою основную версию JPanel вместо JFrame.Если это так, где я могу создать объекты змеи и еды в моем основном классе?

Это детали, которые будут зависеть от вашего действительного кода. Я уверен, что вы это выясните.

А также, могу ли я держать keyListener в классе Snake или я должен помещать его в класс Main?

Я почти никогда не пользуюсь KeyListeners и предпочитаю Key Bindings. Посмотрите на мои many posts on this subject, многие с примером кода для больше.

+0

Спасибо за ответ! Чтобы прояснить это, вы говорите, что у меня есть только один paintComponent() в моей основной, а не в моем классе Snake или Food? Кроме того, я сделаю мою главную расширять JPanel вместо JFrame. Если это так, где я могу создать объекты змеи и еды в моем основном классе? А также, могу ли я сохранить keyListener в классе Snake или поставить его в класс Main? – Samkough

+1

@Samkough: см. Правки –

+0

Хорошо, спасибо большое! Я попробую соло отдохнуть и посмотреть, как это происходит! – Samkough

Смежные вопросы