repaint not being called
-
12-12-2019 - |
Question
Hi I have googled and can't figured out why my paintComp method isnt being called
I have the following code package com.vf.zepto.view;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import javax.imageio.ImageIO;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import com.vf.zepto.view.interfaces.ProcessorPanel;
public class CountryDetailsPanel extends JPanel implements ProcessorPanel, Runnable {
private GridBagConstraints c = new GridBagConstraints();
private String countryName;
private Properties prop = new Properties();
private BufferedImage image;
public CountryDetailsPanel() {
try {
prop.load(new FileInputStream("country.props"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//this.setLayout(new GridBagLayout());
c.gridx = 0;
c.gridy = 0;
c.fill = GridBagConstraints.BOTH;
c.insets = new Insets(5, 5, 5, 5);
this.setPreferredSize(new Dimension(200, 200));
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
try {
if(countryName != null) {
String asset = prop.getProperty(countryName+".flag");
if(!asset.equals(null)) {
image = ImageIO.read(new File(asset));
g.drawImage(image, 0, 0, null);
}
}
}
catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void updateDetails(Object o) {
countryName = (String)o;
SwingUtilities.invokeLater(this);
}
@Override
public void run() {
this.repaint();
}
}
and when calling this.repaint()
expect the paintComponent
method to be called but for love nor money it isnt.
Have tried to force it to use the EDT incase that was the issue but its not.
any ideas?
Solution
You should never call
paintComponent()
therepaint()
method consolidates all requests to change the component (there may be several repaint requests between screen refreshes). It adds an update request to the GUI event queue so that the update will be properly coordinated with other GUI actions (Swing and AWT are not thread-safe). This update request, when processed, callsupdate()
, which callspaint()
, which calls yourpaintComponent()
Why have this:
@Override public void run() { this.repaint(); }
It does not seem of any use (creating a new thread to repaint once? Not to mention the thread is not on EDT rather call repaint()
on the JPanel
instance (if modified externally other than that you shouldnt even worry). However to start a thread which modifeis UI componets use s SwingTimer
/SwingWorker
or SwingUtilities#invokeXXX()
This might not be related but in your code I see this:
if(!asset.equals(null)) { image = ImageIO.read(new File(asset)); g.drawImage(image, 0, 0, null); }
dont use equals()
to compare to a null
value as this might throw a NullPointerException
because you are attempting to
deference a null pointer, for example this code throws a NPE
:
String s=null;
if(!s.equals(null)) {//throws NPE
System.out.println("Here");//is never printed
}
- Also as mKorbel has said (+1 to him) dont do long running tasks in
paintComponent()
declare yourImage
globally, assign it in the constructor and then use it inpaintComponent()
. F.i
rather do:
public class TestPanel extends JPanel {
private Image image;
public TestPanel() {
image = ImageIO.read(new File(asset));
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if(asset!=null) {
g.drawImage(image, 0, 0, null);
}
}
}
OTHER TIPS
Do not load image or another hard or long running code in
paintComponent
Load this
Object
as a local variable and only one timepaintComponent()
is calledimplicitly, when
JComponent
requires repaint, orexplicitly, for example on every of mouse event if one were to invoke
paintComponent()
from aMouseMotionListener
.
If there is animation, then to use Swing Timer and call
repaint()
.