如何在JPanel上显示多个图像?

时间:2017-05-28 06:14:57

标签: java swing jpanel paintcomponent

我一直试图永远解决这个问题,但我似乎无法弄明白。

我想在同一个JPanel中在屏幕上显示多个图像,但出于某种原因,它只显示绘画组件中的最后一个图像

我试图制作一个水果忍者风格的游戏,并希望在动画发生之前将水果画出框架。

有没有人知道如何做到这一点?非常感谢任何帮助...

import javax.swing.*;//imports JPanel class
import java.awt.*;//imports the Graphics class

public class FruitNinja extends JPanel {

   private Image dojo;
   private Image apple;
   private Image orange;
   private Image pineapple;
   private Image strawberry;
   private Image banana;

   private Timer timer;
   private int x, y;

   public FruitNinja() { // a constructor to set up graphics windo
      super();
      setBackground(Color.WHITE);
      loadImage();
      x = 25;
      y = 25;


   }



   private void loadImage() {
      ImageIcon ii = new ImageIcon("Dojo.jpg");
      dojo = ii.getImage();

      ImageIcon oo = new ImageIcon("Orange.ico");
      orange = oo.getImage();

      ImageIcon ss = new ImageIcon("Strawberry.png");
      strawberry = ss.getImage();

      ImageIcon bb = new ImageIcon("Banana.png");
      banana = bb.getImage();

      ImageIcon pp = new ImageIcon("Pineapple.png");
      pineapple = pp.getImage();

      ImageIcon aa = new ImageIcon("Apple.png");
      apple = aa.getImage();


   }

   public void paintComponent(Graphics g){ // draw graphics in the panel

      super.paintComponent(g);// to make panel display correctly
      g.drawImage(dojo, 0,0, this);
      //draws out dojo


      super.paintComponent(g);// to make panel display correctly
      g.drawImage(apple, 0,0, this);

      super.paintComponent(g);// to make panel display correctly
      g.drawImage(orange, 0,0, this);

      super.paintComponent(g);// to make panel display correctly
      g.drawImage(pineapple, 0,0, this);

      super.paintComponent(g);// to make panel display correctly
      g.drawImage(banana, 0,0, this);

      super.paintComponent(g);// to make panel display correctly
      g.drawImage(strawberry, 0,0, this);

      //draws out the fruits somewhere
   }

  /* 
   @Override
    public void actionPerformed(ActionEvent e) {

      x += 5;
      y += 5;

      if (y > getHeight()) {
         y = 25;
         x = 25;
      }
      repaint();
   }
*/

   public static void main(String[] args) { 

      FruitNinja panel = new FruitNinja(); // window for drawing  
      JFrame f = new JFrame(); // the program itself
      f.setTitle("Fruit Ninja");
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//when the X button is clicked, the program quits
      f.setSize(1280,800);//size of the frame
      Container pane = f.getContentPane();//pane refers to the interior of the JFrame

      FruitNinja p1 = new FruitNinja();

      pane.add(p1);//add the FacePanel object to the interior of the frame
      f.setVisible(true);

   }
}

与当前这个问题无关,因为我试图制作一个类似FruitNinja的游戏,我该怎么做才能让代码注册到我的鼠标就在那里(所以它会在我的小鼠在果实上盘旋)?是mouseListenter吗?

2 个答案:

答案 0 :(得分:3)

我建议您查看Painting in AWT and Swing,了解您遇到问题的原因

paintComponent所做的工作之一就是为组件的绘制准备Graphics上下文,它通常通过用组件的背景颜色填充它来实现这一点

因此,基于您的代码,建议您只需在方法开始时调用paintComponent一次

public void paintComponent(Graphics g){ // draw graphics in the panel

  super.paintComponent(g);// to make panel display correctly
  g.drawImage(dojo, 0,0, this);
  //draws out dojo
  g.drawImage(apple, 0,0, this);
  g.drawImage(orange, 0,0, this);
  g.drawImage(pineapple, 0,0, this);
  g.drawImage(banana, 0,0, this);
  g.drawImage(strawberry, 0,0, this);
  //draws out the fruits somewhere
}

所以,现在所有的图像都应该涂在彼此之上

  

与当前这个问题无关,因为我正在尝试制作FruitNinja游戏,我如何制作它以便代码注册我的鼠标就在那里(所以当我的鼠标盘旋在水果上时它切片水果)?是mouseListenter吗?

您可能正在寻找MouseMotionListener,请查看How to Write a Mouse Listener了解详情

答案 1 :(得分:1)

您已将JPanel扩展为JPanel,而xy中的0也是paintComponent()。并且在重写的super方法中,您正在调用 super.paintComponent(g); g.drawImage(apple, 0,0, this); super.paintComponent(g); g.drawImage(orange, 0,0, this); super.paintComponent(g); g.drawImage(pineapple, 0,0, this); super.paintComponent(g); g.drawImage(banana, 0,0, this); super.paintComponent(g); g.drawImage(strawberry, 0,0, this); 类方法次数。因此,您只能看到最后绘制的图像。

改变这个:

  super.paintComponent(g);

  g.drawImage(apple, 0,0, this);
  g.drawImage(orange, 0,0, this);
  g.drawImage(pineapple, 0,0, this);
  g.drawImage(banana, 0,0, this);
  g.drawImage(strawberry, 0,0, this);

要:

  super.paintComponent(g);

  g.drawImage(dojo, x,0, this);
  g.drawImage(apple, x,100, this);
  g.drawImage(orange, 300,100, this);
  g.drawImage(pineapple, x,300, this);
  g.drawImage(banana, 300,0, this);
  g.drawImage(strawberry, 300,300, this);

仍然无法看到其他图像,因为所有图像都在彼此之上。为避免这种情况,您可以执行以下操作:

x

您可以根据需要更改yx cordinate。但这仍然是混乱和烦人,也是耗时的。嗯,有一个更好的方法来做到这一点。那是Layout Manager

想一想将Layout Manager用于程序的方法。这些链接可以帮助您:

在你的问题的最后部分,你提到了

  

如何使代码注册我的鼠标

您需要获取指针的当前位置(ymouseListenter)。

  

是mouseListenter吗?

不,除非你没有很多活动。 MouseMotionListener用于组件上的鼠标事件(按,释放,单击,输入和退出)。

根据上述声明,您需要的是JLabel。它适用于组件上的鼠标移动事件。

更新(根据评论):

  

我不确定你如何使用MouseMotionListener?我已经能够了   为水果/图像设置动画,让它现在在我的框架周围飞舞。怎么做   我使用MouseMotionListener将该果实移出框架一次   我把它悬停在它上面?

这超出了问题的范围,但作为帮助,

那么,你必须将所有图像添加到public void moveImage(ImageIcon icon){ JLabel dojoLabel = new JLabel(); dojoLabel.setIcon(icon); this.add(dojoLabel); dojoLabel.addMouseMotionListener(new MouseMotionAdapter() { public void mouseMoved(MouseEvent evt){ dojoLabel.setLocation(0,0); repaint(); } }); } 中,否则你可以将监听器添加到面板中。由于有多个图像,您必须创建标签。为此,我创建了新方法,Code应如下所示:

loadImage()

现在在ImageIcon内部调用此方法解析Image。无法将JLabel类型添加到ImageIcon。这就是您需要添加private void loadImage() { ImageIcon ii = new ImageIcon("Dojo.jpg"); dojo = ii.getImage(); //..... //move method here moveImage(ii); }

的原因
{{1}}