jPanel не обновляется, пока я не изменю размер окна приложения


У меня есть одна проблема с моей jPanel. У меня есть кнопка, которая PNG изображение из строки ввода (математическая формула), а затем он будет перекрашивать старое изображение в jPanel. И тут возникает проблема. Изображение было изменено, но jPanel не будет перерисовываться, пока я вручную не изменю размер окна приложения.

Похоже, что панель не будет перерисовываться до этого изменения размера. Но я понятия не имею, как это сделать в этой кнопке.

Я пробовал это и это, но ничего не изменилось.

Кстати. Я использую графический интерфейс Строитель в netbeans.

Мой код... первая попытка:

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

И в методе Window class / button:

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

2 ответа:

Вы можете позаботиться об этом с помощью обратной перерисовки нити. Вы можете поместить его в конструктор вашего подкласса JPanel.

Thread repainter = new Thread(new Runnable() {
    @Override
    public void run() {
        while (true) { // I recommend setting a condition for your panel being open/visible
            repaint();
            try {
                Thread.sleep(30);
            } catch (InterruptedException ignored) {
            }
        }
    }
});
repainter.setName("Panel repaint");
repainter.setPriority(Thread.MIN_PRIORITY);
repainter.start();

Вы переопределяете свой метод paint(...), что на самом деле не является хорошей стратегией в любом случае, так как в Swing всякий раз, когда это возможно, попробуйте переопределить свой метод paintComponent(...). Кроме того, я думаю, что вы, возможно, пропустили, чтобы поместить свой код в SwingUtilities.invokeLater(...) метод.Попробуйте свои руки на этом обновленном коде, разместите изображения рядом с вашим .файлы классов (внутри папки изображений), поэтому структура будет,

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