JFrame appears blank when components load images outside of paintComponent (); method

Now this may seem very strange, which is also the reason that I think this is a bug in Java itself.

I am currently creating custom components for my applications. These components ( JComponent size) overwrite the paintComponent(); method paintComponent(); . For some reason, the frame was empty when any of these components was used, as soon as I implemented the images in the components, I made some debuggin, and I learned the following: As soon as the code inside this rewritable method draws an image that was saved in a variable outside the method itself, like a non-static class variable, the frame will be displayed empty until it is displayed, until it is changed. Everything works fine when using images stored in a variable in the paintComponent(); method itself paintComponent(); . What is going on here and how can I solve this problem? I really need to use the images stored in the class variable to cache these images, otherwise it would be very fast to load each image again and again.

Code similar to the example below works fine;

 public class MyComponent extends JComponent { @Override public void paintComponenet(Graphics g) { Image img = ImageIO.read(getClass().getResource("/res/myImg.png")); g.drawImage(img, 0, 0, null); } } 

The frame appears blank when something like this is used;

 public class MyComponent extends JComponent { private Image img = ImageIO.read(getClass().getResource("/res/myImg.png")); @Override public void paintComponenet(Graphics g) { g.drawImage(img, 0, 0, null); } } 

Loading an image (in the example above) inside the constructor or any other method will not have an effect.

NOTE. The frame in which the components are used is not packed before (or after) its display. This should not make any sense, because it works fine when using variables inside the paintComponent(); method itself paintComponent(); .

+1
source share
1 answer

Answer by @trashgod


Make sure that Swing GUI objects are created and processed only in the event dispatch thread .

For example, use the following code to initialize a frame that shows a space, this should solve your problem;

 SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new MyFrame(); } }); 
+2
source

Source: https://habr.com/ru/post/958455/


All Articles