Gray screen saver due to lack of repainting

I am creating a screensaver for my application. This is just a static BufferedImage drawn by Graphics2D, inside a JFrame with no decorations. My problem is that the window is sometimes not drawn properly, which means that it does not always contain my image, it is sometimes just gray. I tried to create a splash screen in the second thread, but that did not help. I could call splashScreen.repaint() every line, but this is nonsense ... Here is my code:

 package SeriousSteve.MapEditor; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.net.URL; import java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.swing.JFrame; /** * Simple splash screen, contains only the image. * * @author m4tx3 */ public class SplashScreen extends JFrame { private BufferedImage image; /** * Constructor. Creates a window with splash screen, loads an image at the * URL specified in imageURL, and finally displays this image. * * @param imageURL URL to the image that you want to put on the splash * screen. */ public SplashScreen() { super("Splash screen"); } public void createSplashScreen(final URL imageURL) { try { image = ImageIO.read(imageURL); } catch (IOException ex) { Logger.getLogger(SplashScreen.class.getName()). log(Level.SEVERE, null, ex); } setUndecorated(true); setSize(image.getWidth(), image.getHeight()); setLocationRelativeTo(null); setVisible(true); createGraphics(); repaint(); } /** * Creates a graphics context and draws a splash screen. */ private void createGraphics() { Graphics2D g = (Graphics2D) getGraphics(); g.drawImage(image, 0, 0, null); } /** * Closes the splash screen and frees the memory taken by the image. * * Call this function when the loading is complete. */ public void close() { setVisible(false); image = null; dispose(); } } 

and

  SplashScreen splashScreen = new SplashScreen(); splashScreen.createSplashScreen(getClass().getResource( "Img/splash.png")); 

Btw., - I create my own splash screen class because I have 2 applications (a game and map editor for it) in 1 bank ... I want to show the splash screen only in the map editor, so I cannot change the manifest file.

Hi

+4
source share
3 answers

Use JLabel instead. Directly framed painting is a bad idea.

See this, it works every time:

 import java.awt.image.BufferedImage; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.SwingUtilities; /** * Simple splash screen, contains only the image. * * @author m4tx3 */ public class SplashScreen extends JFrame { /** * Constructor. Creates a window with splash screen, loads an image at the URL specified in imageURL, and finally displays this image. * * @param imageURL * URL to the image that you want to put on the splash screen. */ public SplashScreen() { super("Splash screen"); } public void createSplashScreen(final URL imageURL) { JLabel splashLabel = new JLabel(new ImageIcon(imageURL)); add(splashLabel); setSize(splashLabel.getPreferredSize()); setUndecorated(true); setLocationRelativeTo(null); setVisible(true); repaint(); } /** * Closes the splash screen and frees the memory taken by the image. * * Call this function when the loading is complete. */ public void close() { setVisible(false); dispose(); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { new SplashScreen().createSplashScreen(new URL( "http://art.gnome.org/download/themes/splash_screens/1334/Splash-GnomeDarkSplashScreen.png")); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); } } 
+5
source

1) g.drawImage(image, 0, 0, null);

it should be

 g2d.drawImage(img, 0, 0, img.getWidth(), img.getHeight(), SplashScreen.this); 

code from

 import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JWindow; public class SplashScreen extends JWindow { private JProgressBar bar; private JLabel label; public SplashScreen(final BufferedImage img) { JPanel panel = new JPanel() { public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); g2d.drawImage(img, 0, 0, img.getWidth(), img.getHeight(), SplashScreen.this); } }; panel.setPreferredSize(new Dimension(img.getWidth(), img.getHeight())); Container content = getContentPane(); content.setLayout(new BorderLayout()); content.add(panel, BorderLayout.NORTH); content.add(label = new JLabel(), BorderLayout.CENTER); content.add(bar = new JProgressBar(), BorderLayout.SOUTH); pack(); setLocationRelativeTo(null); } public void setMessage(String msg) { label.setText(msg); pack(); } public void setProgress(int prog) { bar.setValue(prog); } public void setIndeterminateProgress(boolean value){ bar.setIndeterminate(value); } } 

2) I would suggest using JWindow or undecorated JDialog rather than JFrame (from the tutorial)

+4
source

Cancel the paint method instead of creating your own Graphics .

 @Override public void paint(Graphics g) { g.drawImage(image, 0, 0, null); } 

Each time you call repaint , it, in turn, calls this method. By default, this method will fill the JFrame with the background color (gray).

0
source

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


All Articles