Как отобразить изображение в качестве фона на JPanel - PullRequest
3 голосов
/ 13 ноября 2010

У меня проблема с отображением изображения на JPanel, когда я масштабировал изображение в соответствии с размером JPanel. Изображение не появилось.

   public class createGUII extends JFrame{
        String [] background = {"c1.jpg","c2.jpg","c3.jpg","c4.jpg"};                       
        ArrayList<String> bgPicturesFiles   = new ArrayList<String>(Arrays.asList(background)); 


    JPanel panel;
    ImagePanel imgBg;

    public createGUII(){
        GridBagLayout m = new GridBagLayout();
        Container c = getContentPane();
        c.setLayout (m);
        GridBagConstraints con = new GridBagConstraints();

       //Panel for background
        panel = new JPanel();       
        panel.setSize(600, 600);
        con = new GridBagConstraints();
        con.anchor=GridBagConstraints.CENTER;
        con.gridy = 1;      con.gridx = 0;
        con.gridwidth = 1;  con.gridheight = 1;     
        m.setConstraints(panel, con);   
        c.add(panel);

       //randomized the image files
        Random r = new Random();                        
        int random = r.nextInt(bgPicturesFiles.size());

       //rescale the image according to the size of the JPanel 
        imgBg = new ImagePanel(new ImageIcon(bgPicturesFiles.get(random)).getImage().getScaledInstance(panel.getHeight(), panel.getWidth(),Image.SCALE_SMOOTH));            
        panel.add(imgBg);

        setResizable(false);
        setVisible(true);       
        setExtendedState(getExtendedState()|JFrame.MAXIMIZED_BOTH);             

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new createGUII();       
            }
        });
    }
}



class ImagePanel extends JPanel {
    private Image img;

    public ImagePanel(String img) {
        this(new ImageIcon(img).getImage());
    }

    public ImagePanel(Image img) {
        this.img = img;
        Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
        setPreferredSize(size);
        setMinimumSize(size);
        setMaximumSize(size);
        setSize(size);
        setLayout(null);
        }

    public void paintComponent(Graphics g) {
        g.drawImage(img, 0, 0, null);
        }
}     

Ответы [ 4 ]

1 голос
/ 13 ноября 2010

Посмотрите на это: JPanel фоновое изображение , JPanel с фоновым изображением, с наложением других панелей

Во второй ссылке упоминается, что вам нужно сделать какую-то нестандартную рисование для масштабирования. Это проблема. Я не буду масштабировать изображение каждый раз в методе paintComponent, но сделаю это один раз , если ширина и высота были изменены с момента последнего вызова, и в этом случае воссоздаю BufferedImage, содержащее изображение, которое Вы мигаете каждый раз перед вызовом суперкласса paintComponent, масштабируемого до нужного размера (используйте что-то вроде Масштабирование изображения не работает, когда высота и ширина исходного изображения меньше, высота и ширина масштабирования ). Я вижу проблему, когда при вызове метода paintComponent суперкласса он может попытаться заполнить панель цветом, но вам придется поэкспериментировать.

0 голосов
/ 19 марта 2012

Вот ссылка , которая должна помочь. Однако я нашел способ, который лучше подходил для решения проблемы, с которой я столкнулся , это и я нашел следующее.

Надеюсь, это поможет.

Container con = getContentPane();
final String backgroundPath = "C:\\background.jpg";

ImageIcon imh = new ImageIcon(backgroundPath);
setSize(imh.getIconWidth(), imh.getIconHeight());

JPanel pnlBackground = new JPanel()
{
    public void paintComponent(Graphics g) 
    {
        Image img = new ImageIcon(backgroundPath).getImage();
        g.drawImage(img, 0, 0, null);
    }
};

con.add(pnlBackground);
pnlBackground.setBounds(0, 0, imh.getIconWidth(), imh.getIconHeight());
0 голосов
/ 13 ноября 2010

Проблема в том, что в Java изображения загружаются асинхронно. Из-за этого есть несколько проблем с приведенным выше кодом:

  • Изображение не загружается, поэтому его размеры (-1, -1). Таким образом, размер ImagePanel является недействительным
  • Даже если размеры устанавливаются вручную (т.е. изменяя его на new Dimension(600, 600)), само изображение может не загружаться.
  • Изменение размера JFrame отключено. Если вы позволите, вы сможете нарисовать изображение с помощью приведенного выше кода, искусственно заставив Swing загрузить изображение при изменении размера JFrame

Чтобы обеспечить загрузку, добавьте следующее:

new ImageIcon(img).getImage();

после this.img = img; в конструкторе ImagePanel.

Обратите внимание, что это частично хак - я не эксперт по графическому интерфейсу, но я понимаю, что вышеприведенное можно написать гораздо лучше. Может быть, кто-то еще сможет пролить больше света.

Вот несколько ссылок, которые могут быть полезны:

Надеюсь, это поможет.

0 голосов
/ 13 ноября 2010

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

Приложение: Я добавил пример масштабирования.См. Также Не используйте getScaledInstance() и Опасности Image.getScaledInstance().

import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/** @see http://stackoverflow.com/questions/4170463 */
public class LoadImage extends JPanel {

    private Image image;

    public LoadImage() {
        super(new GridLayout());
        try {
            image = ImageIO.read(new File("image.jpg"));
        } catch (IOException ex) {
            ex.printStackTrace(System.err);
        }
        int w = image.getWidth(null) / 2;
        int h = image.getHeight(null) / 2;
        this.add(new JLabel(new ImageIcon(
            image.getScaledInstance(w, h, Image.SCALE_SMOOTH))));
    }

    private void display() {
        JFrame f = new JFrame("LoadImage");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new LoadImage().display();
            }
        });
    }
}
...