Задача рисования класса JLabel в другой класс JPanel - PullRequest
2 голосов
/ 09 июня 2010

Я создал класс, расширяющий JLabel для использования в качестве моего объекта, перемещающегося вокруг JPanel для игры.

import javax.swing.*;

public class Head extends JLabel {

 int xpos;
 int ypos;

 int xvel;
 int yvel;

 ImageIcon chickie = new ImageIcon(
        "C:\\Users\\jjpotter.MSDOM1\\Pictures\\clavalle.jpg");
 JLabel myLabel = new JLabel(chickie);

 public Head(int xpos, int ypos, int xvel, int yvel){

  this.xpos = xpos;
  this.ypos = ypos;
  this.xvel = xvel;
  this.yvel = yvel;
 }

 public void draw(){
  myLabel.setLocation(xpos, ypos);
 }

 public double getXpos() {
  return xpos;
 }

 public double getYpos() {
  return ypos;
 }

 public int getXvel() {
  return xvel;
 }

 public int getYvel() {
  return yvel;
 }

 public void setPos(int x, int y){

  xpos = x;
  ypos = y;

 }

}

Затем я пытаюсь добавить его на мою JPanel. Отсюда я буду случайным образом увеличивать его координаты x и y, чтобы плавать вокруг экрана. Я не могу заставить его нарисовать себя на JPanel. Я знаю, что здесь отсутствует ключевая концепция, которая включает в себя рисование компонентов на разных панелях. Вот что у меня в классе GamePanel

import java.awt.Dimension;
import java.util.Random;
import javax.swing.*;


public class GamePanel extends JPanel {

 Random myRand = new Random();
 Head head = new Head(20,20,0,0);

 public GamePanel(){

  this.setSize(new Dimension(640, 480));
  this.add(head);

 }

}

Есть предложения, как добавить это в JPanel? Кроме того, это хороший способ сделать изображение случайным образом плавающим по экрану для игры?

Ответы [ 3 ]

2 голосов
/ 09 июня 2010

Прежде всего, для этого не нужно расширять JLabel.

а) Вы устанавливаете размер метки после добавления изображения к метке с помощью:

label.setSize( label.getPreferredSize() );

b) Вам не нужен draw () и все методы установки. Чтобы переместить метку, все, что вам нужно сделать, это использовать:

label.setLocation(...);

в) если вы хотите увеличить местоположение, вы бы использовали что-то вроде:

label.setLocation (label.getLocation (). X + 5, ...);

После того, как вы установите размер и расположение метки, вы можете добавить ее непосредственно на панель. Убедитесь, что вы сделали:

panel.setPreferredSize() 

при добавлении панели на панель содержимого вашего фрейма.

Ваш код слишком расплывчат, чтобы давать конкретные предложения. Если вам нужна дополнительная помощь, оставьте свой SSCCE . Ваша проблема может заключаться в использовании менеджера макета или в том, что вы не используете менеджеры макета.

2 голосов
/ 09 июня 2010

Да, вы должны установить менеджер макета для вашей JPanel (GamePanel) на ноль, который сообщает системе:

Не размещайте это для меня, я сделаю это вручную

редактировать

Думаю, будет понятнее, если я дам вам демонстрацию.

Смотрите этот пример. Как указывает camickr, вам не нужно создавать подклассы компонентов.

import javax.swing.*;
import java.util.Timer;
import java.util.*;

class FloatingDemo {
    public static void main( String [] args ){
        // create the panel         
        JPanel panel = new JPanel();
        panel.setLayout(null);

        // create the label with an image
        final JLabel label = new JLabel(new ImageIcon("StackOverflowLogo.png"));
        label.setSize(label.getIcon().getIconWidth(), 
                      label.getIcon().getIconHeight());
        panel.add( label );

        // create the frame containing both 
        JFrame frame = new JFrame();
        frame.add( panel );
        frame.setSize(800, 600 );
        frame.setVisible( true );

        // move it randomly every second  
        Timer timer = new Timer();
        final Random random = new Random();
        timer.schedule( new TimerTask() {
           public void run(){
                 label.setLocation( random.nextInt(800-label.getWidth()), 
                                    random.nextInt(600-label.getHeight()));       
           } 
        }, 0, 1000 );

    }
}

Кстати, не работает также установка менеджера макета на ноль, но если вы измените размер окна, jpanel автоматически установит местоположение для вас.

демоверсия http://img444.imageshack.us/img444/2567/capturadepantalla201006c.png

1 голос
/ 09 июня 2010

Основная проблема, которую я считаю, заключается в том, что вы на самом деле не добавляете изображение к Head в своем конструкторе.

Что вам нужно сделать, это создать новый ImageIcon, как вы делаете, и в вашем конструкторе сделать что-то такое;

public Head(int xpos, int ypos, int xvel, int yvel){
    // calls the JLabel constructor to create a label with an image
    super(new ImageIcon("C:\\Users\\jjpotter.MSDOM1\\Pictures\\clavalle.jpg"))
    this.xpos = xpos;
    this.ypos = ypos;
    this.xvel = xvel;
    this.yvel = yvel;
}

Это создаст Head с указанным изображением.

Как только вы решите проблему с конструктором, вы можете вызвать setLocation () для вашего Head объекта из JPanel, к которому вы добавили его. Вот как вы можете перемещать его случайным образом.

Кроме того, в JPanel, к которому вы добавляете Head, необходимо убедиться, что для LayoutManaer установлено значение null, чтобы вы могли вручную разместить компонент на панели.

...