图片没有出现在JPanel上?

时间:2015-05-04 15:32:45

标签: java image swing jtable jframe

我在程序中创建的正方形和导入的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
}
}

这就是我用来创建迷宫墙的方法。现在是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;
}
}

接下来是我认为播放器图像出现问题的地方(对于迷宫我觉得它是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)
}
}

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

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

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

此处有新的更新代码:

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

以及布局构造函数

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

1 个答案:

答案 0 :(得分:1)

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

您的Layout类扩展了JPanel并覆盖了paintComponet,但您从未将此类用作JPanel。相反,你在其中使用一些名为panel的其他JPanel变量。摆脱那个变量,而是使用作为Layout类本身的JPanel,至少某些你的问题可能会得到解决。

如,

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();
   }
}

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

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