java - 在调整应用程序窗口大小之前,jPanel 不会刷新

标签 java image swing jpanel paintcomponent

我的 jPanel 有一个问题。 我有一个按钮,其中来自字符串输入(数学公式)的 PNG 图像,然后它将在 jPanel 中重新绘制旧图像。问题就来了。图像已更改,但 jPanel 不会重新绘制,直到我手动调整应用程序窗口的大小。

看起来面板在调整大小之前不会重新绘制。但我不知道如何在该按钮中执行此操作。

我试过thisthis但没有变化。

顺便说一句。我在 netbeans 中使用 GUI Builder。

我的代码...第一次尝试:

public class ImagePanel extends JPanel {

   private String path;
   Image img;
   public ImagePanel() {
        try {
            //save path
            path = "Example5.png";
            //load image
            img = ImageIO.read(new File(path));
        } catch (IOException ex) {
        }
    }
   @Override
   public void paint(Graphics g) {
      //draw the image
      if (show) {
        try {
            if (img != null) {
                img = ImageIO.read(new File(path));
                g.drawImage(img, 0, 0, this);
            }
        } catch (IOException ex) {
        }
     } else {
        show = true;
     }
   }
}

在窗口类/按钮方法中:

   imagePanel = new ImagePanel();
   imagePanel.repaint();
   imagePanel.updateUI();

第二次尝试:

public class ImagePanel extends JPanel {

   private String path;
   Image img;
   ImagePanel(Image img) {
        this.img = img;
   }

   public void setImg(Image img) {
       this.img = img;
   }

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

       // Draw image centered in the middle of the panel
       g.drawImage(img, 0, 0, this);
   }

}

和按钮:

imagePanel.setImg(new ImageIcon("2.png").getImage());
imagePanel.repaint();

最佳答案

您正在重写您的 paint(...) 方法,这无论如何都不是一个好的策略,因为在 Swing 中只要有可能就尝试重写您的 paintComponent(... ) 方法。此外,我猜您可能错过了将代码放入 SwingUtilities.invokeLater(...) 中尝试一下你的更新代码,将图像放在 .class 文件旁边(图像文件夹内),这样结构就可以了,

PanelTest.class      ImagePanel.class        image(Folder)
                                             |     |     |
                                         image1 image2  image3(and so on)

================================================== =====================================

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

public class PanelTest
{
    private URL[] url = new URL[5]; 
    private int counter = 0;
    private ImageIcon image;
    private JButton updateButton;

    public PanelTest()
    {
        try
        {
            for (int i = 0; i < 5; i++)
            {
                url[i] = getClass().getResource("/image/geek" + i + ".gif");
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

    private void createAndDisplayGUI()
    {
        JFrame frame = new JFrame("Panel Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        image = new ImageIcon(url[0]);
        final ImagePanel ip = new ImagePanel(image.getImage());
        updateButton = new JButton("UPDATE");
        updateButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                counter++;
                if (counter < 5)
                {
                    image = new ImageIcon(url[counter]);
                    ip.setImg(image.getImage());
                }
                else
                    counter = -1;
            }
        });

        frame.getContentPane().add(ip, BorderLayout.CENTER);
        frame.getContentPane().add(updateButton, BorderLayout.PAGE_END);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new PanelTest().createAndDisplayGUI();
            }
        });
    }
}
class ImagePanel extends JPanel {

   private String path;
   private Image img;
   ImagePanel(Image img) {
        this.img = img;
   }

   public void setImg(Image img) {
       this.img = img;
       // Added by me, so as to update the image
       // as a new Image is made available.
       repaint();
   }

   /*
    * Added by me, make this a customary
    * habbit to override this method too
    * as you override paintComponent(...)
    * method of the said JComponent.
    */
   @Override
   public Dimension getPreferredSize()
   {
       return (new Dimension(300, 300));    
   }

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

       // Clears the previously drawn image.     
       g.clearRect(0, 0, getWidth(), getHeight());  
       // Draw image centered in the middle of the panel
       g.drawImage(img, 0, 0, this);
   }

}

如果你也想要这些图片,就在这里

GEEK0 GEEK1 GEEK2 GEEK3 GEEK4

关于java - 在调整应用程序窗口大小之前,jPanel 不会刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10535061/

相关文章:

java - 箭头键在自定义搜索组件中不起作用

java - 隐藏打印对话框

java - Android - 如何在 android 中将字符串转换为 utf-8

java - OpenCV 无法在 JAR 文件中运行

node.js - 无法在 Heroku 服务器上上传图片

C# 显示图像(运行时与加载时)

java - JFrame 布局帮助/指南,

java - 修改 UI 线程 View 时 Android UI 不会崩溃

java - 如何将网络摄像头捕获的图像与 Java Swing 中的另一个图像进行匹配?

CSS 动画 : Fading images into one another and animating the image and moving it's direction