1

I have a JPanel window with a few things drawn on it. I am trying to figure out how I can flash the screen, like one simple flash, to get a users attention? I found a previous question on this but it did not work for what I am trying to do. I have a continuous loop that updates the screen based on a few variables. I would just like the screen to flash at a certain point and then go back to normal.

Thanks!

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
kaptaincooke
  • 161
  • 5
  • 14
  • Myself I'd use a [Swing Timer](http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html) ([API](http://docs.oracle.com/javase/7/docs/api/javax/swing/Timer.html)) and call `setBackground(...)` passing in a Color alternating with null in the Timer's ActionListener. What have you tried so far and how isn't it working? Please show your code attempt. – Hovercraft Full Of Eels Jul 31 '12 at 17:10
  • Leave the trench-coat at home and pop a `JOptionPane`. – Andrew Thompson Jul 31 '12 at 23:08
  • You can also vary [saturation](http://stackoverflow.com/a/2124507/230513) or [alpha](http://stackoverflow.com/a/2234020/230513). – trashgod Aug 01 '12 at 00:29
  • I have decided that flashing the window is not the best idea for what I want to accomplish...I would rather have a small window pop up for about a second with some simple text on it...how do I accomplish this? – kaptaincooke Aug 01 '12 at 17:07
  • @kaptaincooke you can use timer to hide a popup, see my last edit for example. – tenorsax Aug 01 '12 at 18:23

3 Answers3

4

You can use Trident to interpolate various properties in your class. Here is a demo that animates panel's background:

import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import org.pushingpixels.trident.Timeline;
import org.pushingpixels.trident.Timeline.RepeatBehavior;

public class TestPanel {
    private static void createAndShowGUI() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel panel = new JPanel();
        panel.add(new JLabel("Some text"));

        frame.add(panel);
        frame.pack();
        frame.setVisible(true);

        final Timeline timeline = new Timeline(panel);
        timeline.addPropertyToInterpolate("background", panel.getBackground(),
                Color.red);
        timeline.setDuration(1000);

        timeline.playLoop(5, RepeatBehavior.REVERSE);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

EDIT: comments to auto hide a popup

You can use timer to hide a popup, for example:

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class TempPopup {

    public static void main(String[] args) {

        JOptionPane pane = new JOptionPane("Message",
                JOptionPane.INFORMATION_MESSAGE);
        final JDialog dialog = pane.createDialog(null, "Title");

        Timer timer = new Timer(2000, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                dialog.setVisible(false);
                dialog.dispose();
            }
        });
        timer.setRepeats(false);
        timer.start();
        dialog.setVisible(true);
        dialog.dispose();
    }
}
tenorsax
  • 21,123
  • 9
  • 60
  • 107
2

Use a glass pane component as in the sample demo below:


import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Demo {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        final JPanel panel = new JPanel();
        frame.add(panel);

        JComponent flashPane = new JComponent() {
            @Override
            public void paint(Graphics g) {
                // Add code to draw whatever you want to grab attention here
                g.setColor(Color.CYAN);
                g.fillRect(0, 0, panel.getWidth(), panel.getHeight());
                super.paint(g);
            }
        };

        panel.getRootPane().setGlassPane(flashPane);
        frame.setBounds(0, 0, 200, 200);
        frame.setVisible(true);

        // Sample loop to flash every 2 seconds
        while(true) {
            try {
                Thread.sleep(2000);
                flashPane.setVisible(true);
                Thread.sleep(200);
                flashPane.setVisible(false);
            } catch(Exception ex) {
            }
        }
    }
}
Sticks
  • 402
  • 3
  • 9
  • 1
    Please, neither `sleep()` on the event dispatch thread nor draw on some other thread. Moreover, "Swing programs should override `paintComponent()` instead of overriding `paint()`."—[*Painting in AWT and Swing: The Paint Methods*](http://java.sun.com/products/jfc/tsc/articles/painting/index.html#callbacks). – trashgod Aug 01 '12 at 00:34
  • Certainly, once implemented in actual code and outside of a quick and dirty main method for example purposes. Impetus here was on using a glasspane and not so much making a bullet proof demo. – Sticks Aug 13 '12 at 11:48
  • Also avoid `null` layouts and swallowed exceptions. – trashgod Aug 13 '12 at 14:53
-1

I'd suggest pseudo code like this:

if(your flash condition is true){
yourFrame.visible = False; // no longer display the frame.
Thread.sleep(500); // waits for half a second.
yourFrame.visible = True; // show the frame again.
}

You may want to validate your view (frame) after to make sure any changes that may of occurred in your model (variables etc) are reflected after the Thread wakes and the frame is displayed again.

James C
  • 464
  • 1
  • 4
  • 12