简体   繁体   English

ImageIcon未在Java中显示

[英]ImageIcon Not Displaying in java

This code is supposed to display a background image and the player. 该代码应显示背景图像和播放器。 But it just comes up with a pink screen. 但是它只是带有一个粉红色的屏幕。 I can't really figure out where the problem is coming from, here is my code. 我真的无法弄清楚问题出在哪里,这是我的代码。

package main;

import java.awt.*;
import javax.swing.ImageIcon;    
import javax.swing.JFrame;

public class Images extends JFrame {

    public static void main(String Args[]) {

        DisplayMode dm = new DisplayMode(800, 600, 16, DisplayMode.REFRESH_RATE_UNKNOWN); // This is going to take 4 parameter, first 2 is x and y for resolotion. Bit depth, the number of bits in a cloour
                                                                                            // 16 is your bit depth. the last one is the monitor refresh, it means it will refres how much it wants
        Images i = new Images(); // making an object for this class
        i.run(dm); // making a run method and is taking the dm as a parameter, in this method we are putting stuff on the screen.
    }

    private Screen s; // Creating the Screen, from the Screen.java
    private Image bg; // Background
    private Image pic; // Face icon
    private boolean loaded; // Making the loaded

    //Run method
    private void run(DisplayMode dm) { // this is where we do things for the screen
        setBackground(Color.PINK); // Setting the Background
        setForeground(Color.WHITE); // Setting the ForeGround
        setFont(new Font("Arial", Font.PLAIN, 24)); // setting the font

        s = new Screen(); // now we can call ALL methods from the Screen object
        try {
            s.setFullScreen(dm, this); // This is setting the full screen, it takes in 2 parameters, dm is the display mode, so its setting the display settings, the next part is the this, what is just s, the screen object.
            loadpics(); // calling the loadpics method
            try { // so if that try block works, then it will put it to sleep for 5 seconds
                Thread.sleep(5000); // its doing this because, at the bottom (s.restorescreen) this makes it into a window again. so it needs to show it for 5 seconds.
            } catch (Exception ex) {
            }
        } finally {
            s.restoreScreen();
        }
    }

    // Loads Pictures
    private void loadpics() {
        System.out.println("Loadpics == true");
        bg = new ImageIcon("Users/georgebastow/Picture/background.jpg").getImage(); // Gets the background
        pic = new ImageIcon("Users/georgebastow/Picture/Player.png").getImage(); // Gets the Player
        System.out.println("Loaded == true in da future!");
        loaded = true; // If the pics are loaded then...    
    }

    public void paint(Graphics g) {
        if (g instanceof Graphics2D) { // This has to happen, its saying if g is in the class Graphics2D, so if we have the latest version of java, then this will run 
            Graphics2D g2 = (Graphics2D) g; // Were making the Text smooth but we can only do it on a graphcis2D object.
            g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); // we are making the text aniti alias and turning it on!(it means making the text smooths! :) )
        }
        if(loaded == true){
            System.out.println("Loaded == true3");
            g.drawImage(bg,0,0,null);
            g.drawImage(pic, 170, 180, null);
            System.out.println("Loaded == true4");
        }
    }    
}

Many Thanks in Advance 提前谢谢了

When using images, you want to load them through URL with Class.getResource() , which returns a URL. 使用图像时,您想使用Class.getResource()通过URL加载图像,该URL返回。 Passing a String the the ImageIcon will cause the image to be looked up through the file system. 传递一个字符串, ImageIcon将导致通过文件系统查找该图像。 Though this may work during development in your IDE, you'll come to find out it won't work at time of deployment. 尽管这可能在IDE的开发过程中起作用,但您会发现它在部署时不起作用。 Better make the changes now. 现在最好进行更改。 To use this method, you want do this 要使用此方法,您需要这样做

ImageIcon icon = new ImageIcon(Images.class.getResource("/Users/georgebastow/Picture/background.jpg"));

For this to work though, you file structure needs to look like this 为了使它起作用,您的文件结构需要看起来像这样

ProjectRoot
          src
             Users
                  georgebastow
                            Picture
                                  background.jpg

A more common approach is just to put the image a reousrces folder in the src 一种更常见的方法是将图像放置在src中的reousrces文件夹中

ProjectRoot
          src
             resources
                     background.jpg

And use this path 并使用此路径

ImageIcon icon = new ImageIcon(Images.class.getResource("/resources/background.jpg"));                     

When you build, your IDE will transfer the images to the class path. 生成时,IDE会将图像传输到类路径。


Side Note 边注

  • Don't paint on top level containers like JFrame . 不要在诸如JFrame顶级容器上绘画。 Instead use JPanel or JComponent and override the paintComponent method. 而是使用JPanelJComponent并重写paintComponent方法。 if using JPanel , you should also call super.paintComponent in the paintComponent method. 如果使用JPanel ,则还应该在paintComponent方法中调用super.paintComponent
  • Run you Swing Apps from the Event Dispatch Thread like this 像这样从事件分发线程运行Swing应用

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

    See Initial Thread 请参阅初始线程

  • Don't call Thread.sleep() . 不要调用Thread.sleep() When running from the EDT (like you should), you will block it. 当从EDT运行时(如您应有的那样),您将阻止它。 Instead use a java.swing.Timer if it's animation you're looking for. 如果您正在寻找动画,请改用java.swing.Timer Even if it's not animation, still use it! 即使它不是动画, 也要使用它! See this example for Timer program. 有关Timer程序,请参见此示例

  • Also as @mKorbel mentioned, you never add anything to the frame. 同样,如@mKorbel所述,您永远不会在框架中添加任何内容。

UPDATE 更新

Run this example. 运行此示例。 I also forgot to mention, when you paint on JPanel you also want to override the getPreferredSize() . 我也忘记提及了,当您在JPanel绘画时,您还想覆盖getPreferredSize() This will give your panel a size. 这将使您的面板大小。

src/resources/stackoverflow5.png

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TestImage {

    public TestImage() {
        JFrame frame = new JFrame("Test Image");
        frame.add(new NewImagePanel());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    public class NewImagePanel extends JPanel {

        private BufferedImage img;

        public NewImagePanel() {
            try {
                img = ImageIO.read(TestImage.class.getResource("/resources/stackoverflow5.png"));
            } catch (IOException ex) {
                System.out.println("Could not load image");
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(600, 600);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TestImage();
            }
        });
    }
}
  1. JFrame isn't proper component (its container) for displaying an Image JFrame不是用于显示Image适当组件(其容器)

  2. usage of paint() for JFrame isn't proper way how to display image or custom painting, graphics JFramepaint()用法不是显示图像或自定义绘画,图形的正确方法

  3. use JLabel with setIcon() in the case isn't JFrame used as container and there are/isn't any JComponent (s) in the JFrame 使用JLabelsetIcon()在这种情况是不JFrame用作容器和有/没有任何JComponent在(一个或多个) JFrame

  4. use JPanel (put to the JFrame.CENTER area) with override paintComponent (instead of paint ) in the case that there will be JPanel used as container for another JComponent (s) 在将JPanel用作另一个JComponent容器的情况下,请使用JPanel (放入JFrame.CENTER区域)并覆盖paintComponent (而不是paint )。

  5. more in Oracle tutorial Working with Images Oracle教程“使用图像”中的更多内容

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

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