【问题标题】:JFrame not showing a pictureJFrame不显示图片
【发布时间】:2012-12-14 01:18:25
【问题描述】:

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

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

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;
    }

}

【问题讨论】:

  • 两件事。 1) steve 为空,因此不绘制任何内容。 2) paintComponent 应该被覆盖自定义绘画,而不是 paint
  • @Vulcan 虽然我同意你的 (paintComponent) 是自定义绘画的更好选择,但JFrame 没有paintComponent 方法;)
  • @MadProgrammer 我完全没有注意到它是一个 JFrame,哎呀!我立即认为它是 JPanel。
  • @Vulcan 不过还是不错的建议 ;)

标签: java swing jframe


【解决方案1】:

这个问题太多了,我不知道从哪里开始......

让我们从头开始...

问题 #1

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

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

这意味着类实例变量永远不会初始化并保持null

问题 #2

虽然没有直接关系,但您永远不会从您的 paint 方法中调用 super.paint。这是一个很大的不,不。您有义务维护油漆链。绘制方法很复杂,而且非常非常重要。

问题 #3

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

您还应该避免使用paint,相反,您应该考虑在可用的地方使用paintComponent

问题 #4

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

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

示例

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

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);

            }

        }
    }
}

阅读

了解更多信息。

【讨论】:

  • 非常感谢!这有助于提升。
  • 很好的描述性答案。 +1
  • +1,但请注意,此图像很可能会在应用时变为 embedded-resource。已部署,应通过URL 访问。
  • @AndrewThompson 好点,我已经添加了额外的代码和 cmets
  • @MadProgrammer 我是摇摆新手,实际上是昨天开始的。从那时起,我到处都找到了你的答案。感谢您的经验 ;) 带有分组列的 JTable 是非常棒的工作。继续做好工作。 ☆(・ω・*)ゞ
猜你喜欢
  • 2015-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-19
  • 1970-01-01
  • 2015-07-15
相关资源
最近更新 更多