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 ответа:
Вы можете позаботиться об этом с помощью обратной перерисовки нити. Вы можете поместить его в конструктор вашего подкласса 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); } }
Если вам тоже нужны изображения, вот они