我的jPanel有一个问题。 我有一个按钮,其中PNG图像来自String输入(数学公式),然后它将重新绘制jPanel中的旧图像。问题出在那里。图像已更改,但jPanel不会重新绘制,直到我手动调整应用程序窗口的大小。
看起来Panel在重新调整大小之前不会重新绘制。但我不知道该怎么做那个按钮。
顺便说一句。我在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;
}
}
}
并在Window类/按钮方法中:
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();
答案 0 :(得分:5)
您正在覆盖paint(...)
方法,这在任何方面都不是一个好策略,因为在Swing中尽可能尝试覆盖您的paintComponent(...)
方法。此外,我猜你可能错过了将你的代码放在SwingUtilities.invokeLater(...)方法中。尝试使用你的更新代码,将图像放在你的.class文件旁边(图像文件夹里面),这样结构就是,< / p>
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);
}
}
如果您也想要图像,那么它们就是
答案 1 :(得分:4)
您可以使用背景重绘线程来处理此问题。您可以将它放在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();