简体   繁体   English

如何将图像添加到 JFrame

[英]how to add image to the JFrame

I need help to add an image to the separate JFrame, but I can't seem to get it to work.我需要帮助才能将图像添加到单独的 JFrame,但我似乎无法让它工作。 Like I want the image to open in a separate frame like when I run this code it opens a blank JFrame.就像我希望图像在单独的框架中打开一样,当我运行此代码时,它会打开一个空白的 JFrame。 d help to add an image to the separate JFrame, but I can't seem to get it to work. d 帮助将图像添加到单独的 JFrame,但我似乎无法让它工作。 Like I want the image to open in a separate frame like when I run this code it opens a blank JFrame.就像我希望图像在单独的框架中打开一样,当我运行此代码时,它会打开一个空白的 JFrame。

import java.awt.event.*; 
import javax.swing.*; 
import java.awt.*;
import javax.swing.JFrame;
class PPJJ extends JFrame implements ActionListener, KeyListener 
{   

public void paint(Graphics g) {  
  
        Toolkit t=Toolkit.getDefaultToolkit();  
        Image i=t.getImage("tenor.gif");  
        g.drawImage(i, 120,100,this);  
          
    }  
    public static void main(String[] args) 
    {
        
        JFrame frame = new JFrame("VOLUNTEER FOR THING"); 
        
        PPJJ obj = new PPJJ(); 
        
        JPanel panel = new JPanel(); 
        
        JLabel lname = new JLabel("Enter your name here");
        JTextField tname = new JTextField(21);
        JButton btn = new JButton("Click"); 
        
        btn.addActionListener(obj); 
        
        tname.addKeyListener(obj); 
        
        panel.add(lname);
        panel.add(tname);
        panel.add(btn); 
        frame.add(panel); 
        frame.setSize(300, 130); 
        frame.show(); 
        frame.setLocationRelativeTo(null);
        
         PPJJ m = new PPJJ();  
        JFrame f =new JFrame();  
        //f.add(m);  
        f.setSize(500,500);  
        f.setVisible(true);  
        frame.add(new JLabel(new ImageIcon("volunteer.jpeg")));

    } 
  
    public void actionPerformed(ActionEvent e) 
    {
        String s = e.getActionCommand(); 
        if(s.equals("Click here")){
            JOptionPane.showMessageDialog(null , "THANKS FOR SIGNING UP");
        } 
    } 
  public void keyPressed(KeyEvent e) {
    if (e.getKeyCode()==KeyEvent.VK_ENTER){
      JOptionPane.showMessageDialog(null , "THANKS FOR SIGNING UP");
    }
  }
    @Override
    public void keyReleased(KeyEvent arg) {}
    @Override
    public void keyTyped(KeyEvent arg) {}
}

Oh, animated GIFs 😓.哦,动画 GIF 😓。

Image handling isn't simple in most cases, but animated GIFs are whole other level of pain ... I mean fun.在大多数情况下,图像处理并不简单,但动画 GIF 完全是另一种痛苦……我的意思是很有趣。

Normally, I prefer to use ImageIO.read , but ImageIO returns a BufferedImage and it's not (easily) possible to then render animated GIFs through it.通常,我更喜欢使用ImageIO.read ,但ImageIO返回一个BufferedImage并且(很容易)不可能通过它渲染动画 GIF。

The "easy" route of displaying animated GIFs is by using Image or ImageIcon .显示动画 GIF 的“简单”方法是使用ImageImageIcon

The first step is get your image "embedded" within your application context (assuming that you're not allowing the user to select the image).第一步是将图像“嵌入”到应用程序上下文中(假设您不允许用户选择图像)。 How this is done will depend on your IDE and build system (Eclipse and Netbeans allow you to simply include them in the src folder, when you're not using Maven).如何完成这将取决于您的 IDE 和构建系统(当您不使用 Maven 时,Eclipse 和 Netbeans 允许您简单地将它们包含在src文件夹中)。

Next, you want to use Class#getResource to obtain a URL reference to the embedded resource.接下来,您想使用Class#getResource来获取对嵌入资源的URL引用。 In this case, you can use ImageIO.read , ImageIcon(URL) or Toolkit#getImage(URL) to load the image.在这种情况下,您可以使用ImageIO.readImageIcon(URL)Toolkit#getImage(URL)来加载图像。 But, as I've said, ImageIO.read isn't going to help you.但是,正如我所说, ImageIO.read不会帮助您。

Next, you need a component which can render the image, lucky for us, Swing can do this pretty much auto magically for use, all we need to do is make sure the component is passed as the ImageObserver reference, for example...接下来,您需要一个可以渲染图像的组件,幸运的是,Swing 可以神奇地自动执行此操作,我们需要做的就是确保该组件作为ImageObserver引用传递,例如...

public class BackgroundPane extends JPanel {
    private Image image;

    public BackgroundPane(Image image) {
        this.image = image;
    }

    @Override
    public Dimension getPreferredSize() {
        Image image = getBackgroundImage();
        return image == null ? super.getPreferredSize() : new Dimension(image.getWidth(this), image.getHeight(this));
    }

    public Image getBackgroundImage() {
        return image;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Image image = getBackgroundImage();
        if (image == null) {
            return;
        }
        int x = (getWidth() - image.getWidth(this)) / 2;
        int y = (getHeight() - image.getHeight(this)) / 2;
        g.drawImage(image, x, y, this);
    }
    
}

Also, note, JLabel supports animated GIFs via it's icon property as well, but look at How to set a background picture in JPanel for reasons why you shouldn't use a JLabel as a background container.另外,请注意, JLabel也通过其icon属性支持动画 GIF,但请查看如何在 JPanel 中设置背景图片,了解不应使用JLabel作为背景容器的原因。

Now, all we need to do is load the image, pass it to the background, add what ever content we need to the component and show it, easy, or at least it should be.现在,我们需要做的就是加载图像,将其传递到背景,将我们需要的任何内容添加到组件并显示它,这很简单,或者至少应该是这样。 ImageIcon and Toolkit#getImage both off load the reading of the image to a background thread, so inspecting the images dimensions before the image is loaded will return 0x0 😓, so, we need to wait for it to load (this is why I prefer ImageIO.read as it won't return until the image is loaded or an error occurs). ImageIconToolkit#getImage都将图像的读取加载到后台线程,因此在加载图像之前检查图像尺寸将返回0x0 😓,因此,我们需要等待它加载(这就是为什么我更喜欢ImageIO.read因为在加载图像或发生错误之前它不会返回)。

Something like...就像是...

Image image = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/images/kitty.gif"));
BackgroundPane backgroundPane = new BackgroundPane(image);
// Did I mention I had this workflow, but ImageIO doesn't
// support animated images, without a lot of work
MediaTracker mt = new MediaTracker(backgroundPane);
mt.addImage(image, 0);
mt.waitForAll();
// The image is now loaded, hooray for us

Runnable example...可运行的示例...

在此处输入图像描述

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    Image image = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/images/kitty.gif"));
                    BackgroundPane backgroundPane = new BackgroundPane(image);
                    // Did I mention I had this workflow, but ImageIO doesn't
                    // support animated images, without a lot of work
                    MediaTracker mt = new MediaTracker(backgroundPane);
                    mt.addImage(image, 0);
                    mt.waitForAll();

                    backgroundPane.setLayout(new GridBagLayout());
                    JLabel label = new JLabel("All your kitty is belong to us");
                    label.setForeground(Color.WHITE);
                    backgroundPane.add(label);

                    JFrame frame = new JFrame();
                    frame.add(backgroundPane);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (InterruptedException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }

    public class BackgroundPane extends JPanel {
        private Image image;

        public BackgroundPane(Image image) {
            this.image = image;
        }

        @Override
        public Dimension getPreferredSize() {
            Image image = getBackgroundImage();
            return image == null ? super.getPreferredSize() : new Dimension(image.getWidth(this), image.getHeight(this));
        }

        public Image getBackgroundImage() {
            return image;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Image image = getBackgroundImage();
            if (image == null) {
                return;
            }
            int x = (getWidth() - image.getWidth(this)) / 2;
            int y = (getHeight() - image.getHeight(this)) / 2;
            g.drawImage(image, x, y, this);
        }

    }
}

Please note...请注意...

If you're not using an animated GIF, then you can just use ImageIO.read instead of Toolkit#getImage and you won't need to wait (as ImageIO.read works in the current thread), in which case the code would look more like...如果您不使用动画 GIF,那么您可以只使用ImageIO.read而不是Toolkit#getImage并且您不需要等待(因为ImageIO.read在当前线程中工作),在这种情况下代码看起来更像...

try {
    BackgroundPane backgroundPane = new BackgroundPane(ImageIO.read(getClass().getResource("/images/kitty.gif")));
    backgroundPane.setLayout(new GridBagLayout());
    JLabel label = new JLabel("All your kitty is belong to us");
    label.setForeground(Color.WHITE);
    backgroundPane.add(label);

    JFrame frame = new JFrame();
    frame.add(backgroundPane);
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
} catch (IOException ex) {
    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}

(the BackgroundPane code doesn't change) BackgroundPane代码不变)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM