2

This is a really general question, but how should I add an animated background for a JPanel. I want the background to be behind all the panel's components and graphics. Right now, I have two separate classes (one for the main panel and the other for the background). The background class uses repaint() to animate a grid moving across the screen. I've tried to make the main panel background transparent, but that hasn't gotten me anywhere.

Even more info: My main panel is part of a CardLayout and it has many different classes in it. So when I'm adding my main panel to my main frame, I'm doing frame.getContentPane().add(cards, BorderLayout.CENTER)

cards is a JPanel which acts as a container for the mainpanel and all the panels inside main panel.

Can anybody help me out in getting a panel animated background?

4

2 回答 2

2

您可以使用Toolkit.getImage()加载动画图像,然后在容器的paintComponent. 确保ImageObserver已设置(不为空)以正确更新动画帧。有关如何加载、观察和更新图像的详细信息,请参阅Java AWT 参考中的图像如何加载附录。

这是一个简单的例子:

import java.awt.*;
import javax.swing.*;
import java.net.URL;

class AnimatedPanelDemo {
    static class ImagePanel extends JPanel {
        private Image image;
        ImagePanel(Image image) {
            this.image = image;
        }
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(image,0,0,getWidth(),getHeight(),this);
        }
    }

    private static void createAndShowUI() {
        try {
            JFrame frame = new JFrame("Image");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLocationRelativeTo(null);

            Image image = Toolkit.getDefaultToolkit().getImage(new URL(
                    "http://duke.kenai.com/iconSized/duke.running.gif"));

            ImagePanel imagePanel = new ImagePanel(image);

            imagePanel.add(new JLabel("Some label"));
            frame.add(imagePanel);
            frame.setSize(100, 100);
            frame.setVisible(true);
        } 
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowUI();
            }
        });
    }
}
于 2013-04-11T04:23:42.987 回答
0

好吧,这是我关于stackoverflow的第一个答案。

将尝试使用这个复杂的 AWT 和 Swift API 帮助我的学习曲线。

下面是扩展 JFrame 的构造函数

package xpto;

import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.event.WindowStateListener;
import java.awt.image.ImageObserver;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

import sun.java2d.SunGraphicsEnvironment;
import java.awt.Graphics;
import java.awt.Graphics2D;

public class FrameLuckyRaffle extends JFrame {

    /**
     * 
     */
    private JLabel backgroundLabel;
    private ImageIcon imageIcon;
    private Image bgImage;


    /**
     * Constructor of this frame.
     */
    public FrameLuckyRaffle(String background, final String dbname) {
        try {
            setTitle("Lucky Raffle of "+ dbname);

            GraphicsConfiguration config = this.getGraphicsConfiguration();
            Rectangle usableBounds = SunGraphicsEnvironment.
                                     getUsableBounds(config.getDevice());
            setDefaultCloseOperation(DISPOSE_ON_CLOSE);
            setBounds(100, 100, (int)(usableBounds.getWidth()*0.8), 
                                (int)(usableBounds.getHeight()*0.8));
            setMinimumSize(new Dimension(1024, 700));
            setResizable(true);
            setDefaultLookAndFeelDecorated(true);

            backgroundLabel = new JLabel() {
               public void paintComponent(Graphics g) {
            // alternative --> g.drawImage(bgImage, 0, 0, null);
            // I prefer to control the new ImageObserver parameter as bellow
                    g.drawImage(bgImage, 0, 0, new ImageObserver() {
                    @Override
                    public boolean imageUpdate(Image img, int infoflags, 
                                               int x, int y, int width, int height) {
                        img.getScaledInstance(getWidth(),getHeight(),
                                              Image.SCALE_FAST);
                        return true;
                    }
               });
           // this is used to have easier control on 
           // image manipulation on my application
              Graphics2D g2d = (Graphics2D)g; 
              super.paintComponent(g2d);
              revalidate();
              repaint();
          }
      };
      backgroundLabel.setBounds(0, 0, 0, 0);
      // this is necessary if you want more child 
      // components to be visible on the JFrame afterwards
      backgroundLabel.setOpaque(false);  
      setContentPane(backgroundLabel);

      addWindowListener(new WindowListener() {
          @Override
          public void windowOpened(WindowEvent e) {
        // Set Frame Background
             imageIcon = new ImageIcon(Toolkit.getDefaultToolkit().
                        createImage(FrameBusinessPure.class.getResource(background)));
             bgImage = imageIcon.getImage().
                       getScaledInstance(getWidth(),getHeight(), Image.SCALE_FAST);
          }
        // Even after closing the window, JVM didn't Garbage Collected the instanced
        // objects, for some reason. Forcing the objects to null helped on that.
          @Override
          public void windowClosed(WindowEvent e) {
              backgroundLabel = null;
              imageIcon = null;
              bgImage = null;
              System.gc();
          }
      });

      addWindowStateListener(new WindowStateListener() {
          @Override
          public void windowStateChanged(WindowEvent e) {

        // if you flush the object on runtime you will surpass the
        // memory leak on using GIFs and most complex graphics

              bgImage.flush();
              bgImage = imageIcon.getImage().
                        getScaledInstance(getWidth(),getHeight(), Image.SCALE_FAST);
          }
       });

    addMouseMotionListener(new MouseMotionListener() {
        @Override
        public void mouseDragged(MouseEvent e) {

      // if you flush the object on runtime you will surpass the
      // memory leak on using GIFs and most complex graphics

           bgImage.flush();
           bgImage = imageIcon.getImage().
                     getScaledInstance(getWidth(),getHeight(), Image.SCALE_FAST);
       });
       }catch (Exception e) {
           e.printStackTrace();
       }
    }
}

请随时通过以下链接了解更多信息

https://www.oracle.com/java/technologies/painting.html

于 2020-06-18T11:58:05.520 回答