Comment définir une image de fond dans JPanel
Bonjour j'utilise JPanel comme conteneur de mon cadre alors je veux vraiment utiliser une image d'arrière-plan dans mon panneau j'ai vraiment besoin d'aide c'est mon code jusqu'à présent . ceci est les mises à jour veuillez vérifier ici est mon code maintenant
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);
}
}
}
3 answers
Il y a un certain nombre de façons d'y parvenir.
Vous Pourriez...
Avertissement
Cavet, en utilisant un JLabel
à cette fin peut entraîner le contenu sur renverser le continer, voir ci-dessous pour plus de détails
Créez un JLabel
, appliquez l'image à sa propriété icon
et définissez-la comme volet de contenu des cadres. Vous devrez alors définir le gestionnaire de mise en page de manière appropriée, car JLabel
n'a pas de mise en page par défaut gestionnaire
JFrame frame = ...;
JLabel background = new JLabel(new ImageIcon(ImageIO.read(...)));
frame.setContentPane(background);
frame.setLayout(...);
frame.add(...);
Mise à Jour avec plein exemple
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();
}
}
});
}
}
Le problème est que le JLabel
ne redimensionne pas l'image lorsque le cadre est redimensionné
AVERTISSEMENT - L'utilisation d'un {[3] } peut causer des problèmes si l'espace requis des composants enfants dépasse la taille de l'image d'arrière-plan, car {[3] } ne calcule pas sa taille préférée en fonction de son contenu, mais en fonction de ses propriétés icon
et text
Vous Pourrait...
Créez un composant personnalisé, s'étendant à partir de quelque chose comme JPanel
et remplacez sa méthode paintComponent
, en peignant l'arrière-plan comme bon vous semble.
Jetez un oeil à Effectuer une peinture personnalisée pour plus de détails.
Cela vous donne la possibilité de décider de la meilleure façon de mettre l'image à l'échelle lorsque son espace disponible change. Bien qu'il existe un certain nombre de façons d'y parvenir, vous devriez lire Les dangers de Image.getScaledInstance () pour en comprendre les avantages et les inconvénients.
Cela soulève un tas de nouvelles questions, à vous voulez les mettre à l'échelle et de préserver le rapport d'aspect? Si oui, voulez-vous adapter l'image à la zone disponible ou la remplir (afin qu'elle couvre toujours l'espace disponible)?
Jetez un oeil à Java: maintien du rapport d'aspect de l'image d'arrière-plan JPanel pour plus de détails.
D'Autres considérations
Les images sont généralement les meilleures chargé via l'API ImageIO
, car il est capable de charger un large éventail d'images, mais lancera également un IOException
en cas de problème.
Voir Lecture/Chargement d'une Image pour plus de détails.
L'emplacement de l'image est également important. Si l'image est externe à l'application (quelque part sur le système de fichiers), vous pouvez utiliser ImageIO.read(new File("/path/to/image"))
. Cependant, si l'image est intégrée dans votre application( stockée dans le pot par exemple), vous devrez utiliser quelque chose plus comme ImageIO.read(getClass().getResource("/path/to/image"))
à la place...
Par exemple...
- Difficulté À Comprendre Comment Définir L'Image D'Arrière-Plan
- Ajouter une image d'arrière-plan à un panneau
- Java: JPanel fond pas mise à l'échelle
Exemple
Cet exemple montre l'utilisation d'un composant personnalisé qui agit comme composant d'arrière-plan. Lorsque les composants de la taille dépasse la taille de l'image d'arrière-plan, l'image est réduite jusqu'à remplissez la zone de contenu disponible.
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;
}
}
, Il serait simple d'avoir aussi l'image réduite lorsque l'espace diminue, mais j'ai délibérément décidé de maintenir l'image à la taille la plus petite.
L'exemple utilise également une algrotithm de mise à l'échelle divide and conquer personnalisée afin de générer un résultat mis à l'échelle de haute qualité.
import java.awt.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
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(getClass().getResource(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);
}
}
}
JPanel ping = new JPanel(){
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
//draw hare what ever you want and it will be in the back of your components
}
};