gpt4 book ai didi

java - 如何在JPanel中设置背景图片

转载 作者:行者123 更新时间:2023-12-01 12:19:12 26 4
gpt4 key购买 nike

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

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

}

最佳答案

有多种方法可以实现这一点。

你可以...

免责声明

Cavet,使用 JLabel为此目的可能会导致内容物溢出容器,请参阅下文了解更多详情

创建一个 JLabel ,将图像应用到它的 icon属性并将其设置为框架内容 Pane 。然后您需要适本地设置布局管理器,如 JLabel没有默认的布局管理器

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

更新完整示例

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

问题在于 JLabel调整框架大小时不会调整图像大小

警告 - 使用 JLabel如果子组件所需的空间超过背景图像的大小,可能会导致问题,如 JLabel不会根据其内容计算其首选大小,而是根据其 icontext特性

你可以...

创建一个自定义组件,从类似 JPanel 扩展并覆盖它的 paintComponent方法,按照您认为合适的方式绘制背景。

看看 Performing Custom Painting更多细节。

这使您能够决定在可用空间发生变化时如何最好地缩放图像。虽然有多种方法可以实现这一点,但您应该通读 The Perils of Image.getScaledInstance()了解它们的优缺点。

这引发了一系列新问题,您想缩放它们并保持纵横比吗?如果是这样,您是要使图像适合可用区域还是填充它(以便它始终覆盖可用空间)?

看看 Java: maintaining aspect ratio of JPanel background image更多细节。

其他注意事项

图片通常最好通过 ImageIO 加载。 API,因为它能够加载各种图像,但也会抛出 IOException当出现问题时。

Reading/Loading an Image更多细节。

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

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

  • 示例

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

    enter image description here
    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;
    }

    }

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

    该示例还使用自定义的分而治之的缩放算法来生成高质量的缩放结果。

    关于java - 如何在JPanel中设置背景图片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22162398/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com