图片没有出现在JPanel上?

时间:2022-01-22 19:43:29

I am having some trouble getting both the squares I created in the program, and the ImageIcon imported to show up on my JPanel. I have been at this for a while now, and still am unable to figure out what I can do to make them show up, and allows the player image to move. Here is the first piece of my code which is the Maze class:

我在程序中创建的正方形和导入的ImageIcon都显示在我的JPanel上时遇到了一些麻烦。我已经在这一段时间了,但仍然无法弄清楚我能做些什么来让它们出现,并允许玩家形象移动。这是我的代码的第一部分,即Maze类:

public class Maze extends JPanel{
int[][][] mazeArray; //will be defined in the loop depending on how many rectangles are spawned, also for making sure the player can't walk over the walls (first is what number wall it is, second is the x coordiante of the wall, and third is the y coordinate of the wall)
//depending on whether or not the rctangle is vertical or horizontal it will use both values for its height and width (vertical would have sideX for the height, and sideY for the width; this would be the opposite for the horizontal rectangle)
int sideX = 50; //x side length
int sideY = 50; //y side length
int x;
int y;
//setters and getters for use later (for changing the rctangles location and size)
public void setSideX(int sideX){
    this.sideX = sideX;
}
public int getSideX(){
    return sideX;
}

public void setSideY(int sideY){
    this.sideY = sideY;
}
public int getSideY(){
    return sideY;
}

public void setCoordinates(int x, int y){
    this.x = x;
    this.y = y;
}

public void setX(int x){
    this.x = x;
}
public int getX(){
    return x;
}

public void setY(int y){
    this.y = y;
}
public int getY(){
    return y;
}
//end setters and getters   
public void generateMaze(){
    //the left side of the maze
    for(int i = 0; i < 10; i++){ //ten blocks on the left side
        setX(0); //x is always 0 for the left side
        setY(getY() + 50); //adds 50 to the previous Y coordinate amount, m   making it go down the whole left side
    }
    setY(0); //set y back to zero to be able to start the right column of blocks
    //the right side of the maze
    for(int i = 0; i < 10; i++){
        setX(500); //x is always 500 for the right side
        setY(getY() + 50); //does the same as it did on the left side,   except on the right
    }
    setY(0); //set y to zero again
    setX(50); //start x at 50 since there is no need to remake the corners
    for(int i = 0; i < 8; i++){ //only goes up to 8 this this time because   the corners of the maze can be ignored
        setY(0); //just in case y changes back
        setX(getX() + 50); //x increases by 50 each time
    }
    setY(500);
    setX(50);
    for(int i = 0; i < 8; i++){ //same as above except for the bottom
        setY(500);
        setX(getX() + 50);
    }
    //the maze walls are now generated
}
public void paintComponent(Graphics g){ //for painting the rectangles
    super.paintComponent(g);
    g.setColor(Color.BLACK);
    g.fillRect(getX(), getY(), sideX, sideY); //uses x and y coordinates defined in the generateMaze loop, and the uses whatever current value for the two side, depending on what type of rectangle it is
}
}

This is what I am using to create the mazes walls. Now comes the Player class which deals with the player image, player coordinates, and the player's movement speed:

这就是我用来创建迷宫墙的方法。现在是Player类,它处理玩家图像,玩家坐标和玩家的移动速度:

public class Player {
//Player starts in the top left corner
int playerX = 50;
int playerY = 50;
int moveSpeed = 5; //I can edit move speed here
Image character;

//getters and setters to utilize the player's location and image
public Player(){ //constructor for initial starting points
    playerX = 50;
    playerY = 50;
    ImageIcon player = new ImageIcon("E://Workspace//Maze//images//Player.jpg");
    character = player.getImage();
}

public void setPlayerX(int playerX){
    this.playerX = playerX;
}
public int getPlayerX(){
    return playerX;
}

public void setPlayerY(int playerY){
    this.playerY = playerY;
}
public int getPlayerY(){
    return playerY;
}

public void setMoveSpeed(int moveSpeed){
    this.moveSpeed = moveSpeed;
}
public int getMoveSpeed(){
    return moveSpeed;
}

public Image getPlayerImage(){
    return character;
}
}

Next is where I think the problem is occurring for the player's image (for the maze I think it is something in the Maze class itself, although it could be a problem in the Layout class as well):

接下来是我认为播放器图像出现问题的地方(对于迷宫我觉得它是Maze类本身的东西,尽管它也可能是Layout类中的一个问题):

public class Layout extends JPanel implements ActionListener { //GUI with a non null FlowLayout
Maze m = new Maze();
Player p = new Player();

//500 x 500 seemed like a good size for the maze game
int x = 500;
int y = 500;
Image player;
JPanel panel;

public Layout() {
    panel = new JPanel();
    panel.setLayout(new FlowLayout()); //same as the JFrame
    panel.addKeyListener(new Move(p));
    panel.setFocusable(true);
    panel.setBackground(Color.YELLOW); //background of the maze
    m.generateMaze(); //create the maze
}

//for use in setting and getting the borders of the game
public void setX(int x){
    this.x = x;
}
public int getX(){
    return x;
}

public void setY(int y){
    this.y = y;
}
public int getY(){
    return y;
}

public JPanel getPanel(){
    return panel;
}
@Override //so it can repaint as needed
protected void paintComponent(Graphics g){
    super.paintComponent(g);
    g.drawImage(p.getPlayerImage(), p.getPlayerX(), p.getPlayerY(), this);
}

public void actionPerformed(ActionEvent ae){
    repaint();
}
}

class Move implements KeyListener { //for player movement
final Player p;
Move(Player p){
    this.p = p;
}

public void keyPressed(KeyEvent press) { //for the movement in the game
    //I used both keys so that if the player woukld like to use WASD or the arrow keys either will work
    if(press.getKeyCode() == KeyEvent.VK_W || press.getKeyCode() == KeyEvent.VK_UP){
        //move up
        p.setPlayerY(p.getPlayerY() - p.getMoveSpeed());
    }
    else if(press.getKeyCode() == KeyEvent.VK_S || press.getKeyCode() == KeyEvent.VK_DOWN){
        //move down
        p.setPlayerY(p.getPlayerY() + p.getMoveSpeed());
    }
    else if(press.getKeyCode() == KeyEvent.VK_A || press.getKeyCode() == KeyEvent.VK_LEFT){
        //move left
        p.setPlayerX(p.getPlayerX() - p.getMoveSpeed());
    }
    else if(press.getKeyCode() == KeyEvent.VK_D || press.getKeyCode() == KeyEvent.VK_RIGHT){
        //move right
        p.setPlayerX(p.getPlayerX() + p.getMoveSpeed());
    }
}


public void keyReleased(KeyEvent release) {
    //nothing is needed here
}

public void keyTyped(KeyEvent e) {
    //does nothing if a key is type (no need for it)
}
}

Lastly is the class that runs it, although I don't think there is any issue here, but just in case I will throw it in here anyway:

最后是运行它的类,虽然我认为这里没有任何问题,但万一我会把它扔进这里:

public class Play extends JPanel {
public static void main(String[]args) {
    play();
}

public static void play() {
    JFrame f = new JFrame();
    Layout l = new Layout();
    JPanel j = l.getPanel();

    f.setTitle("Maze Game for final project");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setSize(l.getX(), l.getY()); //size can be changed in layout
    f.setVisible(true);
    f.add(j); //adds the panel
}
}

I am trying to be able to have the player's image spawn at 50, 50 on start up, and then also have the walls spawn at start up as well. However currently the only thing that is showing up for the JPanel is the yellow background. Help would be greatly appreciated!

我试图让玩家的图像在启动时产生50,50,然后在启动时也会产生墙壁。然而,目前唯一出现在JPanel上的是黄色背景。非常感谢帮助!

New updated code here:

这里有新的更新代码:

    public static void play() {
    JFrame f = new JFrame();
    Layout l = new Layout();

    f.setTitle("Maze Game for final project");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setSize(l.getX(), l.getY()); //size can be changed in layout
    f.add(new Layout()); //adds the panel
    f.setVisible(true);
}

and also for the Layout constructor

还有布局构造函数

    public Layout() {
    setLayout(new FlowLayout());
    addKeyListener(new Move(p));
    setFocusable(true);
    setBackground(Color.YELLOW);
    m.generateMaze();
}

1 个解决方案

#1


I can't say that I've gone through all of your code, but one thing did strike me:

我不能说我已经完成了你的所有代码,但有一件事让我感到震惊:

Your Layout class extends JPanel and overrides paintComponet, but you never use this class as a JPanel. Instead you use some other JPanel variable within it called panel. Get rid of that variable and instead use the JPanel that is the Layout class itself, and at least some of your problems may be fixed.

您的Layout类扩展了JPanel并覆盖了paintComponet,但您从未将此类用作JPanel。相反,你在其中使用一些名为panel的其他JPanel变量。摆脱该变量,而是使用作为Layout类本身的JPanel,至少可以修复一些问题。

e.g.,

public class Layout extends JPanel implements ActionListener {
   Maze m = new Maze();
   Player p = new Player();
   int x = 500;
   int y = 500;
   Image player;

   // JPanel panel;

   public Layout() {
      // panel = new JPanel();
      // panel.setLayout(new FlowLayout()); //same as the JFrame
      // panel.addKeyListener(new Move(p));
      // panel.setFocusable(true);
      // panel.setBackground(Color.YELLOW); //background of the maze

      setLayout(new FlowLayout());
      addKeyListener(new Move(p));
      setFocusable(true);
      setBackground(Color.YELLOW);
      m.generateMaze();
   }

   public void setX(int x) {
      this.x = x;
   }

   public int getX() {
      return x;
   }

   public void setY(int y) {
      this.y = y;
   }

   public int getY() {
      return y;
   }

   // public JPanel getPanel() {
   // return panel;
   // }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.drawImage(p.getPlayerImage(), p.getPlayerX(), p.getPlayerY(), this);
   }

   public void actionPerformed(ActionEvent ae) {
      repaint();
   }
}

Another problem is your use of KeyListeners since Key Bindings would be much preferable here, but I'll leave that for your next question.

另一个问题是你使用KeyListeners,因为Key Bindings在这里更受欢迎,但我会留下你的下一个问题。

Also, you're adding your JPanel to the JFrame after calling setVisible(true) on the JPanel -- don't do this. Call setVisible(true) only after adding all components.

此外,您在JPanel上调用setVisible(true)后将JPanel添加到JFrame - 不要这样做。仅在添加所有组件后调用setVisible(true)。

#1


I can't say that I've gone through all of your code, but one thing did strike me:

我不能说我已经完成了你的所有代码,但有一件事让我感到震惊:

Your Layout class extends JPanel and overrides paintComponet, but you never use this class as a JPanel. Instead you use some other JPanel variable within it called panel. Get rid of that variable and instead use the JPanel that is the Layout class itself, and at least some of your problems may be fixed.

您的Layout类扩展了JPanel并覆盖了paintComponet,但您从未将此类用作JPanel。相反,你在其中使用一些名为panel的其他JPanel变量。摆脱该变量,而是使用作为Layout类本身的JPanel,至少可以修复一些问题。

e.g.,

public class Layout extends JPanel implements ActionListener {
   Maze m = new Maze();
   Player p = new Player();
   int x = 500;
   int y = 500;
   Image player;

   // JPanel panel;

   public Layout() {
      // panel = new JPanel();
      // panel.setLayout(new FlowLayout()); //same as the JFrame
      // panel.addKeyListener(new Move(p));
      // panel.setFocusable(true);
      // panel.setBackground(Color.YELLOW); //background of the maze

      setLayout(new FlowLayout());
      addKeyListener(new Move(p));
      setFocusable(true);
      setBackground(Color.YELLOW);
      m.generateMaze();
   }

   public void setX(int x) {
      this.x = x;
   }

   public int getX() {
      return x;
   }

   public void setY(int y) {
      this.y = y;
   }

   public int getY() {
      return y;
   }

   // public JPanel getPanel() {
   // return panel;
   // }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.drawImage(p.getPlayerImage(), p.getPlayerX(), p.getPlayerY(), this);
   }

   public void actionPerformed(ActionEvent ae) {
      repaint();
   }
}

Another problem is your use of KeyListeners since Key Bindings would be much preferable here, but I'll leave that for your next question.

另一个问题是你使用KeyListeners,因为Key Bindings在这里更受欢迎,但我会留下你的下一个问题。

Also, you're adding your JPanel to the JFrame after calling setVisible(true) on the JPanel -- don't do this. Call setVisible(true) only after adding all components.

此外,您在JPanel上调用setVisible(true)后将JPanel添加到JFrame - 不要这样做。仅在添加所有组件后调用setVisible(true)。