【问题标题】:How to display an image as a background on a JPanel如何在 JPanel 上将图像显示为背景
【发布时间】:2012-03-19 04:27:05
【问题描述】:

当我根据 JPanel 的大小重新缩放图像时,在 JPanel 上显示图像时遇到问题。图像没有出现。

   public class createGUII extends JFrame{
        String [] background = {"c1.jpg","c2.jpg","c3.jpg","c4.jpg"};                       
        ArrayList<String> bgPicturesFiles   = new ArrayList<String>(Arrays.asList(background)); 


    JPanel panel;
    ImagePanel imgBg;

    public createGUII(){
        GridBagLayout m = new GridBagLayout();
        Container c = getContentPane();
        c.setLayout (m);
        GridBagConstraints con = new GridBagConstraints();

       //Panel for background
        panel = new JPanel();       
        panel.setSize(600, 600);
        con = new GridBagConstraints();
        con.anchor=GridBagConstraints.CENTER;
        con.gridy = 1;      con.gridx = 0;
        con.gridwidth = 1;  con.gridheight = 1;     
        m.setConstraints(panel, con);   
        c.add(panel);

       //randomized the image files
        Random r = new Random();                        
        int random = r.nextInt(bgPicturesFiles.size());

       //rescale the image according to the size of the JPanel 
        imgBg = new ImagePanel(new ImageIcon(bgPicturesFiles.get(random)).getImage().getScaledInstance(panel.getHeight(), panel.getWidth(),Image.SCALE_SMOOTH));            
        panel.add(imgBg);

        setResizable(false);
        setVisible(true);       
        setExtendedState(getExtendedState()|JFrame.MAXIMIZED_BOTH);             

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new createGUII();       
            }
        });
    }
}



class ImagePanel extends JPanel {
    private Image img;

    public ImagePanel(String img) {
        this(new ImageIcon(img).getImage());
    }

    public ImagePanel(Image img) {
        this.img = img;
        Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
        setPreferredSize(size);
        setMinimumSize(size);
        setMaximumSize(size);
        setSize(size);
        setLayout(null);
        }

    public void paintComponent(Graphics g) {
        g.drawImage(img, 0, 0, null);
        }
}     

【问题讨论】:

    标签: java image background jpanel


    【解决方案1】:

    看看这个:JPanel background imageJPanel with background image, with other panels overlayed

    第二个链接提到您必须进行一些自定义绘画以进行缩放。这是个问题。我不会在 paintComponent 方法中每次都缩放图像,但如果宽度和高度自上次调用以来已更改,则执行 一次,在这种情况下,重新创建包含图像的 BufferedImage在调用超类 paintComponent 之前,您每次都会对其进行 blit,并按比例放大到正确的大小(使用类似 Image scaling does not work when original image height & width is smaller the scaling height & width 的东西)。我可以看到一个问题,当您调用超类的 paintComponent 方法时,它可能会尝试用颜色填充面板,但您必须进行试验。

    【讨论】:

      【解决方案2】:

      问题是在 Java 中图像是异步加载的。因此,上述代码存在几个问题:

      • 图像未加载,因此其尺寸为 (-1, -1)。因此,ImagePanel 的大小无效
      • 即使手动设置尺寸(即将其更改为 new Dimension(600, 600)),也可能无法加载图像本身。
      • JFrame 调整大小被禁用。如果你允许的话,你可以通过在 JFrame 调整大小时人为地让 Swing 加载图像来获得使用上述代码绘制的图像

      为确保加载,添加以下内容:

      new ImageIcon(img).getImage();
      

      在 ImagePanel 的构造函数中的 this.img = img; 之后。

      请注意,这部分是一个 hack - 我不是 GUI 专家,但我认为上面的内容可以写得更好。也许其他人可能能够揭示更多的光。

      以下是一些可能有用的链接:

      希望这会有所帮助。

      【讨论】:

        【解决方案3】:

        我没有看到您实际阅读图像的位置,正如本示例中所建议的那样。

        附录:我添加了一个缩放示例。另见Don't Use getScaledInstance()The Perils of Image.getScaledInstance()

        import java.awt.EventQueue;
        import java.awt.GridLayout;
        import java.awt.Image;
        import java.io.File;
        import java.io.IOException;
        import javax.imageio.ImageIO;
        import javax.swing.ImageIcon;
        import javax.swing.JFrame;
        import javax.swing.JLabel;
        import javax.swing.JPanel;
        
        /** @see http://stackoverflow.com/questions/4170463 */
        public class LoadImage extends JPanel {
        
            private Image image;
        
            public LoadImage() {
                super(new GridLayout());
                try {
                    image = ImageIO.read(new File("image.jpg"));
                } catch (IOException ex) {
                    ex.printStackTrace(System.err);
                }
                int w = image.getWidth(null) / 2;
                int h = image.getHeight(null) / 2;
                this.add(new JLabel(new ImageIcon(
                    image.getScaledInstance(w, h, Image.SCALE_SMOOTH))));
            }
        
            private void display() {
                JFrame f = new JFrame("LoadImage");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.add(this);
                f.pack();
                f.setLocationRelativeTo(null);
                f.setVisible(true);
            }
        
            public static void main(String[] args) {
                EventQueue.invokeLater(new Runnable() {
        
                    @Override
                    public void run() {
                        new LoadImage().display();
                    }
                });
            }
        }
        

        【讨论】:

        • 图片不是在ImagePanel构造函数中通过ImageIcon读取创建的吗?看起来有点乱,但它可能有效。
        • 我认为标题可能是错误的。实际上我想要做的是重新缩放图像。如果我没有重新缩放图像,图像会出现在屏幕上,但是当我重新缩放它时,它不会出现。
        • 如果我只使用这段代码,图像就会出现.. imgBg = new ImagePanel(new ImageIcon(bgPicturesFiles.get(random)).getImage());
        • @Jessy:我在示例中添加了缩放,但我不确定您的代码为什么会失败。
        【解决方案4】:

        这是一个link,应该会有所帮助。但是我发现了一种更适合我遇到的问题的方法this 就是我发现的,以下是我从中得到的。

        我希望这会有所帮助。

        Container con = getContentPane();
        final String backgroundPath = "C:\\background.jpg";
        
        ImageIcon imh = new ImageIcon(backgroundPath);
        setSize(imh.getIconWidth(), imh.getIconHeight());
        
        JPanel pnlBackground = new JPanel()
        {
            public void paintComponent(Graphics g) 
            {
                Image img = new ImageIcon(backgroundPath).getImage();
                g.drawImage(img, 0, 0, null);
            }
        };
        
        con.add(pnlBackground);
        pnlBackground.setBounds(0, 0, imh.getIconWidth(), imh.getIconHeight());
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-02-04
          • 1970-01-01
          • 2018-08-10
          • 2016-02-15
          • 1970-01-01
          • 1970-01-01
          • 2011-03-20
          相关资源
          最近更新 更多