Search code examples
javaimageswingpaintjcomponent

JFrame doesn't appear with red background


I have strange problem when running my Java program. It's designed to:

  1. run external app specified in bat file and display fullscreen wallpaper
  2. "hide" wallpaper for some time when buttons combination pressed
  3. warn user that 5sec left so he can save work
  4. when timeout occures display again fullscreen wallpaper and do some other stuff from bats
  5. quit program when button combination pressed

warinng user is realized as displaying fullscreen red box for 200ms I'm using visible function to do this.

It shows standard fullscreen frame discaring color settings. but only when I comment frame.setUndecorated(true). when uncommented I see only icon in taskbar.

On the other hand when I launch (Using BlueJ) only function visible the red frame is displayed for specified amount of time. Simply standalone function works perfectly (in my oppinion) even if frame.setUndecorated(true) is used .

what can be wrong that I can't launch that red frame in fullscreen?

olympicApp class:

import java.awt.*;
import java.awt.Color;
import java.awt.event.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.Graphics;
import java.awt.image.*;
import java.io.*;
import java.io.IOException;
import javax.imageio.*;
import javax.swing.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JComponent;

public class olympicApp extends JComponent {
    alertApp alert;  
    BufferedImage img;
    public olympicApp()
    {
        try 
        {
            img = ImageIO.read(new File("wallpaper.jpg"));
        } 
        catch (IOException e) 
        {
        }
    }

    public void paint(Graphics g) 
    {
        g.drawImage(img, 0, 0, null);
    }

    public Dimension getPreferredSize() 
    {
        if (img == null) 
        {
            return new Dimension(200,200);
        } 
        else 
        {
            return new Dimension(img.getWidth(null), img.getHeight(null));
        }
    }

    public static void visible()
    {
        JFrame frame = new JFrame();
        frame.getContentPane().setBackground(Color.red);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.dispose();
        //frame.setUndecorated(true);
        frame.setAlwaysOnTop(true);
        frame.pack();
        frame.setVisible(true);
        try 
        {
            frame.setVisible(true);
            Thread.sleep(500);
            frame.setVisible(false);
        } 
        catch(Exception ex) 
        {
        }
        frame.setAlwaysOnTop(false);
        frame.setVisible(false);
    }

    public static void main(String[] args)
    {
        //alertApp reminder = new alertApp();
        try
        {
            Process process = Runtime.getRuntime().exec("start-lv.bat");
            Thread.sleep(500);
        }
        catch (IOException | InterruptedException e)
        {
        }
        JFrame f = new JFrame("olympic");
        f.setExtendedState(JFrame.MAXIMIZED_BOTH);
        f.setUndecorated(true);
        f.setAlwaysOnTop(true);     
        f.addWindowListener(new WindowAdapter()
        {
            public void windowClosing(WindowEvent e) 
            {
                System.exit(0);
            }
        });
        f.add(new olympicApp());
        f.pack();
        f.setVisible(true);
        f.addKeyListener(new KeyListener() 
        {
            public void keyPressed(KeyEvent kevt)
            {
                if(kevt.getKeyChar()=='l') 
                {
                    if(kevt.isAltDown())
                    {
                        f.setAlwaysOnTop(false);
                        f.setVisible(false);
                        try 
                        {
                            Thread.sleep(5*1000);
                            visible();
                            Thread.sleep(5*1000);
                            //Process process = Runtime.getRuntime().exec("saving.bat");
                            Thread.sleep(500);
                            f.setAlwaysOnTop(true);
                            f.setVisible(true);
                            Process process2 = Runtime.getRuntime().exec("kopia.bat");
                        } 
                        catch(IOException | InterruptedException e)
                        {
                        }
                    }                 
                }

                if(kevt.getKeyChar()=='q') 
                {
                    if(kevt.isAltDown())
                    {
                        System.exit(0);
                    }                 
                }
            }

            public void keyTyped(KeyEvent kevt) 
            {
            }

            public void keyReleased(KeyEvent kevt) 
            {
            }
        });
    }
}

Solution

  • I would imagine that you're going to have to do something in here...

    public class alertApp {
    
        public static void main(String[] args) {
            // Sample loop to flash every 2 seconds
        }
    }
    

    This is called when your program starts and where you should put the code to get the program running

    I would also strogly recommend that you take a look at Code Conventions for the Java TM Programming Language, it will make it easier for people to read your code and for you to read others

    As well as Concurrency in Swing and How to use Swing Timers which will help you solve other potential issues

    I put neccessary code in visible funciton. I can see the frame but color information is discarted. Thanks for Concurrency and Timers, but I think the problem isn't connected to thread.sleep()

    Then you didn't read the links...

    public void keyPressed(KeyEvent kevt) {
        if (kevt.getKeyChar() == 'l') {
            if (kevt.isAltDown()) {
                f.setAlwaysOnTop(false);
                f.setVisible(false);
                try {
                    Thread.sleep(5 * 1000);
                    visible();
                    Thread.sleep(5 * 1000);
                    //Process process = Runtime.getRuntime().exec("saving.bat");
                    Thread.sleep(500);
                    f.setAlwaysOnTop(true);
                    f.setVisible(true);
                    Process process2 = Runtime.getRuntime().exec("kopia.bat");
                } catch (IOException | InterruptedException e) {
                }
            }
        }
    

    keyPressed is executed within the context of the Event Dispatching Thread, so when you call Thread.sleep, it prevents the EDT from processing the Event Queue, preventing it from painting or responding to other events