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

How do I display multiple Images on JPanel?

我一直想弄清楚这个问题,但我似乎无法弄清楚。

我想在同一个 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 吗?

我建议您查看 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
}

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

Also unrelated to this current question, since I'm trying to make a FruitNinja game, how do I make it so the code registers that my mouse is there(so it slices the fruit when my mouse hovers over the fruit)? is it mouseListenter?

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

您已经扩展了 JPanel,并且在 JPanel 中您绘制了相同的 xy,即 0。并且在重写的 paintComponent() 方法中,您调用了 super class 方法的次数。因此,您只能看到最后绘制的图像。

改变这个:

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

您可以根据需要更改 xy 坐标。但这仍然是混乱和烦人的,而且很耗时。嗯,有更好的方法来做到这一点。即Layout Manager.

想办法在你的程序中使用Layout Manager。这些link可能对你有帮助:

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

how do I make it so the code registers that my mouse is there

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

is it mouseListenter?

不,除非您没有很多活动,否则不会。 mouseListenter 用于组件上的鼠标事件(按下、释放、单击、进入和退出)。

根据上面的说法,你需要的是MouseMotionListener。它用于组件上的鼠标移动事件。

更新(根据评论):

I'm not really sure how you use a MouseMotionListener? I've been able to animate the fruit/images so it's flying around my frame now. How do I use the MouseMotionListener to move that fruit off of the frame once I hover over it?

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

好吧,为此您必须将所有图像添加到 JLabel 中,否则您可以将侦听器添加到面板。由于有多个图像,您必须创建标签。为此,我创建了新方法,代码应如下所示:

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

现在在您的 loadImage() 中调用此方法解析 ImageIcon。无法将 Image 类型添加到 JLabel。这就是为什么你需要添加 ImageIcon.

private void loadImage() {
      ImageIcon ii = new ImageIcon("Dojo.jpg");
      dojo = ii.getImage();
      //.....
      //move method here
      moveImage(ii);
}