Как установить фоновое изображение в JPanel

привет, я использую 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 , примените изображение к его JLabel и установите его как область содержимого фреймов. Затем вам нужно будет установить диспетчер компоновки соответствующим образом, так как у JLabel нет менеджера макета по умолчанию

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

Проблема с этим заключается в том, что JLabel не будет изменять размер изображения при изменении размера кадра

ПРЕДУПРЕЖДЕНИЕ. Использование JLabel может вызвать проблемы, если требуемое пространство дочерних компонентов превышает размер фонового изображения, поскольку JLabel не вычисляет его предпочтительный размер на основе его содержимого, а на основе его свойств icon и text

Ты мог…

Создайте пользовательский компонент, простирающийся от чего-то вроде JPanel и переопределите его метод paintComponent , paintComponent фон по своему усмотрению.

Взгляните на « Выполнение пользовательской живописи» для получения более подробной информации.

Это дает вам возможность решить, как лучше масштабировать изображение при изменении пространства. Несмотря на то, что это может быть достигнуто, вы должны прочитать « The Perils of Image.getScaledInstance» (), чтобы понять их плюсы и минусы.

Это вызывает множество новых вопросов, вам нужно масштабировать их и сохранять соотношение сторон? Если да, хотите ли вы поместить изображение в доступную область или заполнить его (чтобы он всегда охватывал доступное пространство)?

Взгляните на Java: поддерживаем соотношение сторон JPanel background image для более подробной информации.

Другие соображения

Изображения, как правило, лучше всего загружаются через API ImageIO , поскольку он способен загружать широкий спектр изображений, но также будет генерировать IOException когда что-то пойдет не так.

См. Раздел « Чтение / загрузка изображения» для получения более подробной информации.

Также важно расположение изображения. Если изображение является внешним по отношению к приложению (где-то в файловой системе), вы можете использовать ImageIO.read(new File("/path/to/image")) . Однако, если изображение встроено в ваше приложение (например, в Jar), ​​вам нужно будет использовать нечто вроде ImageIO.read(getClass().getResource("/path/to/image")) . ..

Например…

  • Проблемы с настройкой фонового изображения
  • Добавить фоновое изображение на панель
  • Java: JPanel не масштабируется

пример

Этот пример демонстрирует использование настраиваемого компонента, который действует как фоновый компонент. Когда размер компонентов превышает размер фонового изображения, изображение масштабируется для заполнения доступной области содержимого.

введите описание изображения здесь

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

Было бы просто также, чтобы изображение уменьшалось, когда пространство уменьшалось, но я намеренно решил сохранить изображение в наименьшем размере.

В этом примере также используется пользовательский алгоритм разделения и масштабирования, чтобы генерировать высококачественный масштабированный результат.

 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 } }; 
  • Использование нескольких JFrames: хорошая или плохая практика?
  • Выбор нескольких строк в JTable
  • Что такое MVP и MVC и в чем разница?
  • Неверная операция поперечного streamа
  • Почему мы должны использовать sp для размеров шрифтов в Android?
  • ProgressBar в Javafx не обновляется в блоке onAction
  • SwingWorker, Thread.sleep () или javax.swing.timer? Мне нужно «вставить паузу»,
  • Панель действий Android, например, твиттер
  • Android ViewPager с нижними точками
  • JButton ActionListener - обновление GUI только после нажатия JButton
  • установить и отключить иконки JToggleButton
  • Давайте будем гением компьютера.