如何在JPanel中设置背景图片 [英] How to set a background picture in JPanel

查看:140
本文介绍了如何在JPanel中设置背景图片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好我使用JPanel作为我框架的容器然后我真的想在我的面板中使用背景图片我真的需要帮助这是我的代码到目前为止。这是更新,请点击这里查看我现在的代码

hello i am using JPanel as my container of my frame then i really want to used a background picture in my Panel i really need help this is my code so far . this is the updates please check here is my code now

 import java.awt.*;
import javax.swing.*;
import java.awt.event.*;


public class imagebut extends JFrame
{

public static void main(String args [])
{
    imagebut w = new imagebut();
    w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    w.setSize(300,300);
    w.setVisible(true);

}
public imagebut()
{   

    setLayout(null); // :-)
    PicPanel mainPanel = new PicPanel("picturename.jpg");
    mainPanel.setBounds(0,0,500,500);
    add(mainPanel);


}

class PicPanel extends JPanel{

    private BufferedImage image;
    private int w,h;
    public PicPanel(String fname){

        //reads the image
        try {
            image = ImageIO.read(new File(fname));
            w = image.getWidth();
            h = image.getHeight();

        } catch (IOException ioe) {
            System.out.println("Could not read in the pic");
            //System.exit(0);
        }

    }

    public Dimension getPreferredSize() {
        return new Dimension(w,h);
    }
    //this will draw the image
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.drawImage(image,0,0,this);
    }
}

}


推荐答案

可以通过多种方式实现这一目标。

There are any number of ways this might be achieved.

为此目的使用 JLabel 进行封锁可能导致内容超过溢出合并者,请参阅下文了解更多详情

Cavet, using a JLabel for this purpose may result in the contents over spilling the continer, see below for more details

创建 JLabel ,将图像应用于其中 icon 属性并将其设置为框架内容窗格。然后你需要适当地设置布局管理器,因为 JLabel 没有默认布局管理器

Create a JLabel, apply the image to it's icon property and set this as the frames content pane. You would then need to set the layout manager appropriately, as JLabel doesn't have a default layout manager

JFrame frame = ...;
JLabel background = new JLabel(new ImageIcon(ImageIO.read(...)));
frame.setContentPane(background);
frame.setLayout(...);
frame.add(...);

使用完整示例进行更新

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class LabelBackground {

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

    public LabelBackground() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                try {
                    // Load the background image
                    BufferedImage img = ImageIO.read(new File("/path/to/your/image/on/disk"));

                    // Create the frame...
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                    // Set the frames content pane to use a JLabel
                    // whose icon property has been set to use the image
                    // we just loaded                        
                    frame.setContentPane(new JLabel(new ImageIcon(img)));

                    // Supply a layout manager for the body of the content
                    frame.setLayout(new GridBagLayout());
                    GridBagConstraints gbc = new GridBagConstraints();
                    gbc.gridwidth = GridBagConstraints.REMAINDER;
                    // Add stuff...
                    frame.add(new JLabel("Hello world"), gbc);
                    frame.add(new JLabel("I'm on top"), gbc);
                    frame.add(new JButton("Clickity-clackity"), gbc);

                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException exp) {
                    exp.printStackTrace();
                }
            }
        });
    }
}

这个问题是不会调整图像大小

The problem with this is the JLabel won't resize the image when the frame is resized

警告 - 使用<$ c $如果子组件的所需空间超过背景图像的大小,则c> JLabel 可能会导致问题,因为 JLabel 不计算它的首选大小基于它的内容,但基于其图标文本属性

WARNING - Using a JLabel could cause issues if the required space of the child components exceeds the size of the background image, as JLabel does not calculate it's preferred size based on it's contents, but based on its icon and text properties

创建一个自定义组件,从 JPanel 扩展并覆盖它 paintComponent 方法,根据需要绘制背景。

Create a custom component, extending from something like JPanel and override it's paintComponent method, painting the background as you see fit.

看看执行自定义绘画以获取更多详细信息。

Take a look at Performing Custom Painting for more details.

这使您能够决定图像在缩放时的最佳缩放程度可用空间变化。虽然有很多方法可以实现,但您应该阅读 Image.getScaledInstance()的危险,以了解它们的优点和缺点。

This provides you with the ability to decide how best the image should be scaled when it's available space changes. While there are a number of ways this might be achived, you should read through The Perils of Image.getScaledInstance() to understand the pros and cons of them.

这引起了一堆对于你想要缩放它们并保持纵横比的新问题?如果是这样,你想让图像适合可用区域还是填充它(因此它总是覆盖可用空间)?

This raises a bunch of new questions, to you want to scale them and preserve the aspect ratio? If so, do you want to fit the image to available area or fill it (so it will always cover the available space)?

看看Java:维护JPanel背景图片的宽高比了解更多详情。

其他注意事项

图像通常最好通过<$ c加载$ c> ImageIO API,因为它能够加载各种图像,但在出现问题时也会抛出 IOException

Images are generally best loaded through the ImageIO API, as it's capable of loading a wide range of images, but will also throw an IOException when something goes wrong.

请参阅阅读/加载图片以获取更多详细信息。

See Reading/Loading an Image for more details.

图像的位置也很重要。如果映像在应用程序外部(文件系统的某个位置),则可以使用 ImageIO.read(新文件(/ path / to / image))。但是,如果图像嵌入在您的应用程序中(例如存储在Jar中),则需要使用更像 ImageIO.read(getClass()。getResource(/ path / to /)的内容。图像))而不是...

The location of the image is also important. If the image is external to the application (somewhere on the file system), you can use ImageIO.read(new File("/path/to/image")). However, if the the image is embedded within your application (stored within the Jar for example), you will need to use something more like ImageIO.read(getClass().getResource("/path/to/image")) instead...

例如......

  • Trouble Figuring Out How To Set Background Image
  • Add an Background image to a Panel
  • Java: JPanel background not scaling

示例

此示例演示如何使用充当背景组件的自定义组件。当组件大小超过背景图像的大小时,图像将按比例放大以填充可用内容区域。

This example demonstrates the use of a custom component which acts as the background component. When the components size exceeds the size of the background image, the image is scaled up to fill the available content area.

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.HeadlessException;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class SimpleBackground {

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

    public SimpleBackground() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                try {
                    BackgroundPane background = new BackgroundPane();
                    background.setBackground(ImageIO.read(new File("/path/to/your/image/on/your/disk")));

                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setContentPane(background);
                    frame.setLayout(new GridBagLayout());
                    GridBagConstraints gbc = new GridBagConstraints();
                    gbc.gridwidth = GridBagConstraints.REMAINDER;
                    frame.add(new JLabel("Hello world"), gbc);
                    frame.add(new JLabel("I'm on top"), gbc);
                    frame.add(new JButton("Clickity-clackity"), gbc);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException exp) {
                    exp.printStackTrace();
                }
            }
        });
    }

    public class BackgroundPane extends JPanel {

        private BufferedImage img;
        private BufferedImage scaled;

        public BackgroundPane() {
        }

        @Override
        public Dimension getPreferredSize() {
            return img == null ? super.getPreferredSize() : new Dimension(img.getWidth(), img.getHeight());
        }

        public void setBackground(BufferedImage value) {
            if (value != img) {
                this.img = value;
                repaint();
            }
        }

        @Override
        public void invalidate() {
            super.invalidate();
            if (getWidth() > img.getWidth() || getHeight() > img.getHeight()) {
                scaled = getScaledInstanceToFill(img, getSize());
            } else {
                scaled = img;
            }
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (scaled != null) {
                int x = (getWidth() - scaled.getWidth()) / 2;
                int y = (getHeight() - scaled.getHeight()) / 2;
                g.drawImage(scaled, x, y, this);
            }
        }

    }

    public static BufferedImage getScaledInstanceToFill(BufferedImage img, Dimension size) {

        double scaleFactor = getScaleFactorToFill(img, size);

        return getScaledInstance(img, scaleFactor);

    }

    public static double getScaleFactorToFill(BufferedImage img, Dimension size) {

        double dScale = 1;

        if (img != null) {

            int imageWidth = img.getWidth();
            int imageHeight = img.getHeight();

            double dScaleWidth = getScaleFactor(imageWidth, size.width);
            double dScaleHeight = getScaleFactor(imageHeight, size.height);

            dScale = Math.max(dScaleHeight, dScaleWidth);

        }

        return dScale;

    }

    public static double getScaleFactor(int iMasterSize, int iTargetSize) {

        double dScale = (double) iTargetSize / (double) iMasterSize;

        return dScale;

    }

    public static BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor) {

        return getScaledInstance(img, dScaleFactor, RenderingHints.VALUE_INTERPOLATION_BILINEAR, true);

    }

    protected static BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor, Object hint, boolean bHighQuality) {

        BufferedImage imgScale = img;

        int iImageWidth = (int) Math.round(img.getWidth() * dScaleFactor);
        int iImageHeight = (int) Math.round(img.getHeight() * dScaleFactor);

//        System.out.println("Scale Size = " + iImageWidth + "x" + iImageHeight);
        if (dScaleFactor <= 1.0d) {

            imgScale = getScaledDownInstance(img, iImageWidth, iImageHeight, hint, bHighQuality);

        } else {

            imgScale = getScaledUpInstance(img, iImageWidth, iImageHeight, hint, bHighQuality);

        }

        return imgScale;

    }

    protected static BufferedImage getScaledDownInstance(BufferedImage img,
            int targetWidth,
            int targetHeight,
            Object hint,
            boolean higherQuality) {

        int type = (img.getTransparency() == Transparency.OPAQUE)
                ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;

        BufferedImage ret = (BufferedImage) img;
        if (targetHeight > 0 || targetWidth > 0) {
            int w, h;
            if (higherQuality) {
                // Use multi-step technique: start with original size, then
                // scale down in multiple passes with drawImage()
                // until the target size is reached
                w = img.getWidth();
                h = img.getHeight();
            } else {
                // Use one-step technique: scale directly from original
                // size to target size with a single drawImage() call
                w = targetWidth;
                h = targetHeight;
            }

            do {
                if (higherQuality && w > targetWidth) {
                    w /= 2;
                    if (w < targetWidth) {
                        w = targetWidth;
                    }
                }

                if (higherQuality && h > targetHeight) {
                    h /= 2;
                    if (h < targetHeight) {
                        h = targetHeight;
                    }
                }

                BufferedImage tmp = new BufferedImage(Math.max(w, 1), Math.max(h, 1), type);
                Graphics2D g2 = tmp.createGraphics();
                g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
                g2.drawImage(ret, 0, 0, w, h, null);
                g2.dispose();

                ret = tmp;
            } while (w != targetWidth || h != targetHeight);
        } else {
            ret = new BufferedImage(1, 1, type);
        }
        return ret;
    }

    protected static BufferedImage getScaledUpInstance(BufferedImage img,
            int targetWidth,
            int targetHeight,
            Object hint,
            boolean higherQuality) {

        int type = BufferedImage.TYPE_INT_ARGB;

        BufferedImage ret = (BufferedImage) img;
        int w, h;
        if (higherQuality) {
            // Use multi-step technique: start with original size, then
            // scale down in multiple passes with drawImage()
            // until the target size is reached
            w = img.getWidth();
            h = img.getHeight();
        } else {
            // Use one-step technique: scale directly from original
            // size to target size with a single drawImage() call
            w = targetWidth;
            h = targetHeight;
        }

        do {
            if (higherQuality && w < targetWidth) {
                w *= 2;
                if (w > targetWidth) {
                    w = targetWidth;
                }
            }

            if (higherQuality && h < targetHeight) {
                h *= 2;
                if (h > targetHeight) {
                    h = targetHeight;
                }
            }

            BufferedImage tmp = new BufferedImage(w, h, type);
            Graphics2D g2 = tmp.createGraphics();
            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
            g2.drawImage(ret, 0, 0, w, h, null);
            g2.dispose();

            ret = tmp;
            tmp = null;

        } while (w != targetWidth || h != targetHeight);
        return ret;
    }

}

这是一件简单的事情当空间减小时,图像也会缩小,但我故意决定将图像维持在最小尺寸。

It would be a simple matter to also have the image scaled down when the space decreases, but I deliberately decided to maintain the image at it's smallest size.

这个例子也利用了自定义的划分和征服缩放algrotithm以生成高质量的缩放结果。

The example also makes use of a custom divide and conquer scaling algrotithm in order to generate a high quality scaled result.

这篇关于如何在JPanel中设置背景图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆