【问题标题】:Set background image for JPanel in Java Breakout Game在 Java Breakout Game 中为 JPanel 设置背景图像
【发布时间】:2013-03-18 14:53:52
【问题描述】:

好的,这似乎是一项非常简单的任务,但我似乎无法理解。我想要的只是有一个图像(jpg)作为我的突破游戏的背景。这是我的代码:

主类:

import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;


public class Breakout extends JFrame {

    public Breakout()
    {             
        add(new BreakBoard());
        setTitle("Breakout");
        setSize(BreakCommons.WIDTH, BreakCommons.HEIGTH);
        setLocationRelativeTo(null);
        setIgnoreRepaint(true);
        setResizable(false);
        setVisible(true);
    }

    public static void main(String[] args) {
        new Breakout();
    }
}

板级:

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;


public class BreakBoard extends JPanel implements BreakCommons {

    ImageIcon icon = new ImageIcon("../pacpix/love.jpg"); 
    Timer timer;
    String message = "Game Over";
    BreakBall ball;
    BreakPaddle paddle;
    BreakBrick bricks[];
    boolean ingame = true;
    int timerId;


    public BreakBoard() {
        setOpaque(false);
        addKeyListener(new TAdapter());
        setFocusable(true);
        //setBackground(Color.white);
        bricks = new BreakBrick[30];
        setDoubleBuffered(true);
        timer = new Timer();
        timer.scheduleAtFixedRate(new ScheduleTask(), 1000, 10);
    }

    public void paint(Graphics g) {
        super.paint(g);
        g.drawImage(icon.getImage(), 10, 10, this);

        if (ingame) {
            g.drawImage(ball.getImage(), ball.getX(), ball.getY(),
                        ball.getWidth(), ball.getHeight(), this);
            g.drawImage(paddle.getImage(), paddle.getX(), paddle.getY(),
                        paddle.getWidth(), paddle.getHeight(), this);

            for (int i = 0; i < 30; i++) {
                if (!bricks[i].isDestroyed())
                    g.drawImage(bricks[i].getImage(), bricks[i].getX(),
                                bricks[i].getY(), bricks[i].getWidth(),
                                bricks[i].getHeight(), this);
            }
        } else {

            Font font = new Font("Verdana", Font.BOLD, 18);
            FontMetrics metr = this.getFontMetrics(font);

            g.setColor(Color.BLACK);
            g.setFont(font);
            g.drawString(message,
                         (BreakCommons.WIDTH - metr.stringWidth(message)) / 2,
                         BreakCommons.WIDTH / 2);
        }


        Toolkit.getDefaultToolkit().sync();
        g.dispose();
    }

所以图像存储在变量icon 中,并且位于我的源文件(连同我的类)中,所以我知道路径是正确的。我尝试将框架和面板设置为setOpaque(false),但这只是将背景更改为默认灰色。我可以通过setBackground(Color.white);轻松设置背景颜色,但是如何设置图片呢?

我尝试将图像放入 JLabel 中,然后将其添加到 JPanel,但没有产生任何结果。我将不胜感激,并在此先感谢!我可以根据需要提供更多信息。

【问题讨论】:

    标签: java swing jpanel paint imageicon


    【解决方案1】:

    简单的方法首先为jpane创建一个单独的类

    import java.awt.Color;
    import java.awt.GradientPaint;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.Paint;
    import javax.swing.ImageIcon;
    import javax.swing.JPanel;
    
    public class JPanelDemo extends JPanel {
        /**
         * 
         */
         private static final long serialVersionUID = 1L;
         private static final Color BACKGROUND      = Color.black;
         private static final Color BACKGROUND_2    = Color.WHITE;
         String path="/img/background.jpg";
    
        @Override
        protected void paintComponent(Graphics g) {
            Graphics2D graphics = (Graphics2D) g.create();        
            int midY = 100;
            Paint topPaint = new GradientPaint(0, 0, BACKGROUND,0, midY, BACKGROUND_2);
            graphics.setPaint(topPaint);
            graphics.fillRect(0, 0, getWidth(), midY);        
            Paint bottomPaint = new GradientPaint(0, midY + 1, BACKGROUND_2,0, getHeight(), BACKGROUND);
            graphics.setPaint(bottomPaint);
            graphics.fillRect(0, midY, getWidth(), getHeight());
            Image img = new ImageIcon(getClass().getResource(path)).getImage();
            int imgX = img.getWidth(null);
            int imgY = img.getHeight(null);
            graphics.drawImage(img, (getWidth() - imgX) / 2, (getHeight() - imgY) / 2, imgX, imgY, null);
          //  graphics.dispose();
        }
    }
    

    怎么用

    JPanelDemo contentPane = new JPanelDemo();
    

    【讨论】:

      【解决方案2】:

      这是一个带有背景图像的 JPanel。在您的代码中使用 IPanel 代替 JPanel。根据需要进行调整以满足您的需求。

      public class IPanel extends JPanel {
      private static final long serialVersionUID = 1L;
      private Image             imageOrg         = null;
      private Image             image            = null;
      {
          addComponentListener(new ComponentAdapter() {
              @Override
              public void componentResized(final ComponentEvent e) {
                  final int w = IPanel.this.getWidth();
                  final int h = IPanel.this.getHeight();
                  image = w > 0 && h > 0 ? imageOrg.getScaledInstance(w, h, Image.SCALE_SMOOTH) : imageOrg;
                  IPanel.this.repaint();
              }
          });
      }
      
      public IPanel(final Image i) {
          imageOrg = i;
          image = i;
      }
      
      @Override
      public void paintComponent(final Graphics g) {
          super.paintComponent(g);
          if (image != null)
              g.drawImage(image, 0, 0, null);
      }
      }
      

      例子:

          final JPanel j = new IPanel(image);
          j.setLayout(new FlowLayout());
          j.add(new JButton("YoYo"));
          j.add(new JButton("MaMa"));
          j.add(new JLabel(icon));
      

      生产:

      【讨论】:

      • 你能解释一下它的作用/它如何适合我的代码吗?
      • 这是一个带有背景图像的 JPanel。在您的代码中使用 IPanel 代替 JPanel。根据需要进行调整。
      • 那行不通。我很困惑,我会把这个放在哪里?我的代码实际上没有我能看到的地方。你能解释一下你的代码的逻辑吗?
      • @CodeAddict - 现在我很困惑......你说它不起作用但你不知道在哪里使用它。此代码是一个带有背景图像的 JPanel。它被称为IPanel。不要使用标准的 JPanel,而是使用这个 IPanel。您可能需要进行一些调整 - 例如为图像添加零参数 CTOR 和 setter()。然后可能将“BreakBoard 扩展 JPanel”更改为“BreakBoard 扩展 IPanel”。请参阅我的答案中的示例。将其放在 main() 方法中进行测试。希望这会有所帮助。
      • 哈哈,我试着把它放在我的代码中,但它不起作用,这就是原因。所以用IPanel代替JPanel,IPanel的工作方式和JPanel一样吗?我真的认为它比这更简单,比如最多五行代码。哇xD
      【解决方案3】:

      我终于让它工作了!

      public class BreakBoard extends JPanel implements BreakCommons {
          Image love;
      
          public BreakBoard() {
              ImageIcon icon = new ImageIcon(this.getClass().getResource("../pacpix/love.jpg"));
              love = icon.getImage();
          }
      
          public void paint(Graphics g) {
              super.paint(g);
              Graphics2D g2d = (Graphics2D) g;
              g2d.drawImage(love, 10, 10, null); 
          }
      }
      

      对于将来的搜索或好奇的搜索,我使用了http://zetcode.com/tutorials/javagamestutorial/basics/。适合初学者的好网站! (或者那些需要愚蠢才能理解的人)

      【讨论】:

      • 接受这个作为正确的解决方案,所以其他人会在搜索时看到它:)
      • 即使它看起来有效 - 在 Swing 中覆盖 paint 是错误的方法:相反,覆盖 paintComponent
      【解决方案4】:
      JPanel panel = new JPanel()    
      {       
                @Override
                public void paintComponent(Graphics g) 
                {     
                      g.drawImage(ImageObject, 0, 0, null);
                }
      };
      

      【讨论】:

      • 与之前的答案相比没有什么新的,是吗?也就是说,除了您引入了至少两个错误并使其不那么通用...
      猜你喜欢
      • 2014-05-07
      • 1970-01-01
      • 2012-08-04
      • 1970-01-01
      • 1970-01-01
      • 2014-01-19
      • 2016-08-10
      • 2021-08-07
      • 2014-04-05
      相关资源
      最近更新 更多