JFrame没有显示图片 [英] JFrame not showing a picture

查看:138
本文介绍了JFrame没有显示图片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是我到目前为止的代码:
所有导入都是正确的。我确定。 :D

Following is the code I have so far: All the imports are correct. I'm sure. :D

当我运行程序时,我得到的只是一个空白帧,没有图片。它应该出现。

When I run the program, all I get is a blank frame, without the picture. It should show up.

public class WindowPractice extends JFrame {

   final static int width= 800;
   final static int height= 400;
   int x;
   int y;
   Image steve;
   Dimension gamesize= new Dimension (width, height);
    public WindowPractice(){
        setTitle ("Hangman");
        setSize (gamesize);
        setVisible (true);
        setResizable (false);
        setLocationRelativeTo (null);
        setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);


    }
    public static void main (String[] args) {
        new WindowPractice();
        ImageIcon steve= new ImageIcon ("Libraries/Pictures/ba190cd951302bcebdf216239e156a4.jpg");
        JLabel imageLabel = new JLabel(steve);

    }
    public void paint(Graphics g){

        g.setColor(Color.red);
        //g.fillRect(  x, y, 100, 20);
        g.drawImage(steve, x, y,this);


        x= 150;
        y= 250;
    }

}


推荐答案

这有很多问题我不知道从哪里开始...

There are so many things wrong with this I'm not sure where to start...

让我们从头开始......

Let's start at the beginning...

问题#1

您声明一个名为 steve的实例字段在你的 WindowPractice 类中,这很好,但是在你的main方法中,你声明一个名为 steve 您正在使用对加载图像的引用...

You declare a instance field called steve in you WindowPractice class, this is fine, but in your main method, you declare ANOTHER variable called steve which you are using the reference to the loaded image...

public static void main(String[] args) {
    new WindowPractice();
    ImageIcon steve = new ImageIcon("C:/Users/shane/Dropbox/issue459.jpg");
    JLabel imageLabel = new JLabel(steve);
}

这意味着类实例变量从未初始化并保持 null

This means that the class instance variable is never initialised and remains null.

问题#2

虽然没有直接相关,但您从未通过 paint 方法调用 super.paint 。这是一个很大的NO,NO。您有义务维护油漆链。油漆方法很复杂,非常非常重要。

While not directly related, you never call super.paint from your paint method. This is a BIG NO, NO. You are obligated to maintain the paint chain. The paint methods are complex and very, very important.

问题#3

你永远不应该覆盖顶级容器(例如 JFrame ),也不应该覆盖它的任何 paint 方法。这有很多原因,但在前两个容器中,大多数顶级容器实际上包含许多组件( JRootPane ,它包含玻璃窗格,内容窗格,图层窗格和菜单栏可以坐在你的绘画工作上,一般来说,它们不是双缓冲的,这意味着你的绘画更新会闪烁并且看起来很糟糕;)

You should never override a top level container (such as JFrame) nor you should you override any of it's paint methods. There are lots of reasons for this, but among the top two are, most top level containers actually contain a number of components (JRootPane, which houses the glass pane, content pane, layer pane and menu bar) which can sit over your painting efforts and, generally, they're not double buffered, meaning you paint updates will flicker and look horrible ;)

您还应该避免使用 paint ,相反,您应该考虑使用 paintComponent 它可用的位置。

You should also avoid using paint, instead, you should look towards using paintComponent where it's available.

问题#4

ImageIcon 是不是你加载图片的最佳选择。我不使用它们的主要原因是你不知道加载的图像何时才真正可用(实际上有方法,但坦率地说, ImageIO 只是更简单)。这是1999年的一个很棒的功能,当时拨号速度大约在14.4k左右,但现在只有... ...

ImageIcon is not you best choice for loading images. The main reason I don't use them is that you have no idea of when the image being loaded will actually become available (actually there are ways, but to be frank, ImageIO is just simpler). This was a great feature back in 1999 when dial-up speeds where around the 14.4k mark, but now days...

ImageIO 支持更广泛的图片格式,支持图像的读取和写入,并保证当方法返回(成功)时,图像像素数据可供您的应用程序使用。

ImageIO supports a wider range of picture formats, supports reading and writing of images and guarantees that when the method returns (successfully), the image pixel data is available to your application.

示例

这是一个更好的(恕我直言)方法......

Here's a better (IMHO) approach...

public class BetterDrawing {

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

    public BetterDrawing() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new PaintPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class PaintPane extends JPanel {

        private BufferedImage background;

        public PaintPane() {
            try {
                background = ImageIO.read(new File("/path/to/image"));
                // Use this instead to load embedded resources instead
                //background = ImageIO.read(getClass().getResource("/path/to/image"));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            if (background != null) {

                int x = (getWidth() - background.getWidth()) / 2;
                int y = (getHeight() - background.getHeight()) / 2;

                g.drawImage(background, x, y, this);

            }

        }
    }
}

读一读

  • Performing custom painting
  • Working with Images

更多信息。

这篇关于JFrame没有显示图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆