2013-06-24 3 views
0

Я пытался выяснить, как добавить изображение в JPanel в качестве фона, но все же иметь полный контроль над размещением JButtons, JLabels и т. Д. Это один из методов, который я нашел, но он сбой, а не загружая изображение или кнопки. Вот код:Изображение не загружается на JPanel?

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JButton; 
import java.awt.BorderLayout; 
import java.awt.FlowLayout; 
import java.awt.GridLayout; 

public class PanelDemo extends JFrame { 
private static final long serialVersionUID = 1L; 

private JButton btn1 = new JButton("EASY"); 
private JButton btn2 = new JButton("MEDIUM"); 
private JButton btn3 = new JButton("HARD"); 
private JButton btn4 = new JButton("High Score"); 

public PanelDemo() { 
    super("Image Panel Demo"); 

    JPanel panel = new ImagePanel(
      new FlowLayout(FlowLayout.CENTER, 50, 180)); 

    JPanel panelbtn = new JPanel(new GridLayout(4, 1)); 

    btn1.setBackground(new java.awt.Color(0, 0, 0)); 
    btn1.setFont(new java.awt.Font("Showcard Gothic", 1, 24)); 
    btn1.setForeground(new java.awt.Color(0, 255, 102)); 
    btn2.setBackground(new java.awt.Color(0, 0, 0)); 
    btn2.setFont(new java.awt.Font("Showcard Gothic", 1, 24)); 
    btn2.setForeground(new java.awt.Color(0, 255, 102)); 
    btn3.setBackground(new java.awt.Color(0, 0, 0)); 
    btn3.setFont(new java.awt.Font("Showcard Gothic", 1, 24)); 
    btn3.setForeground(new java.awt.Color(0, 255, 102)); 
    btn4.setBackground(new java.awt.Color(0, 0, 0)); 
    btn4.setFont(new java.awt.Font("Showcard Gothic", 1, 24)); 
    btn4.setForeground(new java.awt.Color(0, 255, 102)); 

    panel.add(panelbtn); 

    panelbtn.add(btn1); 
    panelbtn.add(btn2); 
    panelbtn.add(btn3); 
    panelbtn.add(btn4); 

    add(panel, BorderLayout.CENTER); 

    setSize(640, 480); 

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
} 

public static void main(String... args) { 
    new PanelDemo().setVisible(true); 
    } 
} 

ImagePanel.java

import java.awt.Graphics; 
import java.awt.Image; 
import java.awt.LayoutManager; 

import javax.swing.ImageIcon; 
import javax.swing.JPanel; 

public class ImagePanel extends JPanel { 
private static final long serialVersionUID = 1L; 

String imageFile = "/rsc/img/background.jpg"; 

public ImagePanel() { 
    super(); 
} 

public ImagePanel(String image) { 
    super(); 
    this.imageFile = image; 
} 

public ImagePanel(LayoutManager layout) { 
    super(layout); 
} 

public void paintComponent(Graphics g) { 
    ImageIcon imageicon = new ImageIcon(getClass().getResource(imageFile)); 
    Image image = imageicon.getImage(); 

    super.paintComponent(g); 

    if (image != null) 
     g.drawImage(image, 0, 0, getWidth(), getHeight(), this); 
    } 
} 

Ошибка:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException 
at javax.swing.ImageIcon.<init>(Unknown Source) 
at ImagePanel.paintComponent(ImagePanel.java:27) 
at javax.swing.JComponent.paint(Unknown Source) 
at javax.swing.JComponent.paintChildren(Unknown Source) 
at javax.swing.JComponent.paint(Unknown Source) 
at javax.swing.JComponent.paintChildren(Unknown Source) 
at javax.swing.JComponent.paint(Unknown Source) 
at javax.swing.JLayeredPane.paint(Unknown Source) 
at javax.swing.JComponent.paintChildren(Unknown Source) 
at javax.swing.JComponent.paintToOffscreen(Unknown Source) 
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source) 
at javax.swing.RepaintManager$PaintManager.paint(Unknown Source) 
at javax.swing.RepaintManager.paint(Unknown Source) 
at javax.swing.JComponent.paint(Unknown Source) 
at java.awt.GraphicsCallback$PaintCallback.run(Unknown Source) 
at sun.awt.SunGraphicsCallback.runOneComponent(Unknown Source) 
at sun.awt.SunGraphicsCallback.runComponents(Unknown Source) 
at java.awt.Container.paint(Unknown Source) 
at java.awt.Window.paint(Unknown Source) 
at javax.swing.RepaintManager$3.run(Unknown Source) 
at javax.swing.RepaintManager$3.run(Unknown Source) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source) 
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source) 
at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source) 
at javax.swing.RepaintManager.access$1000(Unknown Source) 
at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source) 
at java.awt.event.InvocationEvent.dispatch(Unknown Source) 
at java.awt.EventQueue.dispatchEventImpl(Unknown Source) 
at java.awt.EventQueue.access$200(Unknown Source) 
at java.awt.EventQueue$3.run(Unknown Source) 
at java.awt.EventQueue$3.run(Unknown Source) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
at java.awt.EventQueue.dispatchEvent(Unknown Source) 
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) 
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) 
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) 
at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
at java.awt.EventDispatchThread.run(Unknown Source) 

Кроме того, если кто-нибудь знает лучший способ поставить фоновое изображение на JPanel, гороховой скажи. Заранее спасибо.

+0

Не лучший способ, но попробуйте просто передать имя файла и путь в этот образ ImageIcon imageicon = new ImageIcon (imageFile); ' –

+2

Какая строка выбрасывает исключение? Вы уверены, что ищете изображение по пути относительно пути к классу? Для чего это стоит, я настоятельно призываю вас игнорировать смысл JavaDevil, но вводить в заблуждение. Придерживайтесь ресурсов, как вы делаете. Но загрузите с помощью 'ImageIO.read (...)'. Также * никогда не загружайте изображение в метод 'paintComponent (...)'. Это не имеет смысла и бесполезно замедляет ваш рендеринг. Загрузите его один раз, возможно, в конструктор, а затем сохраните его. –

+0

Должен был уточнить, что я имел в виду; Предложение состояло в том, чтобы просто попробовать, поскольку из трассировки стека видно, что ImageIcon не инициализирован из-за NullPointer - может быть путь, хотя –

ответ

1
String imageFile = "/rsc/img/background.jpg"; 

Я не думаю, что вы должны использовать ведущий «/». Это означает, что вы ищете каталог «rsc» в корне вашего диска C :.

См. Учебник Swing по адресу How to Use Icons для примера загрузки изображения.

btn1.setFont(new java.awt.Font("Showcard Gothic", 1, 24)); 

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

+0

Кроме того, никогда не загружайте изображение повторно в 'paintComponent (...)'. Загрузите его один раз в конструктор или другой метод и сохраните его в переменной. 'PaintComponent (...)' должен быть тощим и средним и иметь дело только с живописью и живописью. 1+ –

+0

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

+1

Хорошая точка, подумайте об этом еще раз ... – camickr