【问题标题】:How do you add a JPanel onto another JPanel that has graphics?如何将 JPanel 添加到另一个具有图形的 JPanel 上?
【发布时间】:2011-02-21 22:25:48
【问题描述】:

基本上,我试图做的是将 JPanel 添加到另一个 JPanel 上,该 JPanel 使用 paintComponent() 方法在其上绘制了图形。但是我尝试添加的 JPanel 没有显示,因为它被带有图形的 JPanel 覆盖了。

我怎样才能做到这一点,当我将 JPanel 添加到带有图形的那个时,它会在前面显示 JPanel 而不是被图形覆盖?

感谢所有答案! :)

如果您需要代码,请告诉我,我很乐意将它放在这里。

好的,代码如下:

package javavideogame;
public class Game extends JPanel implements ActionListener, Runnable
{

 public Game(MainCharacter character)
 {
     setLayout(null);
     setFocusable(true);

 }


 public void paintComponent(Graphics g)
 {
     super.paintComponent(g);
     g.drawImage(ground, 0, 0, this);
     g.drawImage(character.getImage(), character.getX(), character.getY(), this);
     g.setColor(Color.RED);
     g.drawRect(10, 10, character.getMaxHealth(), 10);
     g.fillRect(10, 10, character.getHealth(), 10);
     g.dispose();
 }

 public void getInventoryScreen()
 {
     Main.inv = new Inventory();
     Main.game.add(Main.inv);
 }
}

这是我添加到 Game JPanel 中的 JPanel 的代码

public class Inventory extends JPanel
{
     public Inventory()
     {
         setLayout(null);
         setSize(400, 300);
         setBackground(Color.BLACK);
         addKeyListener(this);
         setFocusable(true);
     }
}

【问题讨论】:

  • 应始终发布 SSCCE,这样我们就不必猜测您可能会或可能不会做什么。此外,很多时候在创建 SSCCE 时,您会发现问题,因此您甚至不需要发布问题。
  • 我认为您不应该处理传递给您的 paintComponent 方法的 Graphics 对象。我不确定这会产生什么影响,但看起来不太好。 OTOH,是的,请在使用完之后释放您自己创建的 Graphics 对象,但不是因为您没有创建它而传递给 paint 或 paintComponent 的那个。
  • @Hovercraft 你的方法奏效了!我拿出了 g.dispose();它完全有效!我只是把它放在那里,因为我有点按照教程所说的去做。不过谢谢!
  • 作为旁注,调用 getAnything(...) 并使用 void 并实际设置一些东西是一个糟糕的命名决定。我建议将其称为 initInventoryScreen(),作为一种良好做法。
  • 是的,如果您从 BufferedImage 创建 Graphics 对象,本教程是正确的。否则,您可能会耗尽系统资源。但是传入您的paintComponent 方法的Graphics 对象是由Graphics 子系统(我认为)创建的,并且可以用于绘制组件的边框和子项。由于您添加的 JPanel 是一个子组件,因此如果您处置 Graphics 对象,它可能不会被绘制。对于那里的任何专家——请纠正我在这里可能做出的任何不正确的假设——谢谢!

标签: java swing graphics jpanel


【解决方案1】:

自定义绘画是通过覆盖 paintComponent(...) 方法来完成的。我的猜测是您正在覆盖 paint() 方法。

阅读 Custom Painting 上的 Swing 教程中的这一部分。因为您覆盖了错误的方法,所以您最终会先绘制孩子,然后在顶部完成自定义绘制。

如果您需要更多帮助而不是发布您的 SSCCE 来展示问题。

【讨论】:

    【解决方案2】:

    提醒一下:java.awt 和 javax.swing 不能很好地混合。当您在一个面板上绘画并尝试向其添加 JPanel 时,您一定会在某个地方遇到问题。更好的解决方案是使用 2 个不同的 JPanel,一个用于图形,一个用于库存。

    类似这样的:

    JPanel mainPanel = new JPanel(); //will hold BOTH panels
    JPanel gamePanel = new Game(myCharacter); //declare game panel
    JPanel inventoryPanel = new Inventory(); //declare inventory panel
    
    //set up some layout
    mainPanel.setLayout(new GridLayout(2, 1));
    
    //add the graphics panel, then add the inventory
    mainPanel.add(gamePanel);
    mainPanel.add(inventoryPanel);
    

    这将防止您的挥杆和 awt 组件混合并为您省去很多麻烦。

    【讨论】:

      猜你喜欢
      • 2011-02-25
      • 2012-07-07
      • 1970-01-01
      • 1970-01-01
      • 2021-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多