-5

I need to create a simple delay (3-5 seconds) so that a window can be read before being disposed of.

I've found a million examples on line, but they all seem to give me the same issue. My code:

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import javax.swing.JLabel;

public class GrantedPane extends JPanel {

private static final long serialVersionUID = 1L;

public GrantedPane() {

    JFrame frame = new JFrame();
    frame.setUndecorated(true);
    frame.setSize(400, 150);
    frame.setContentPane(this);
    frame.setLocationRelativeTo(null);
    frame.setSize(400, 80);

    setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
    setBorder(new CompoundBorder(BorderFactory.createLineBorder(Color.WHITE), new EmptyBorder(20, 20, 20, 20)));

    JLabel grantTitle = new JLabel(" Key Accepted ");
    grantTitle.setForeground(Color.YELLOW);
    grantTitle.setFont(new Font("Enter The Grid", Font.PLAIN, 32));
    grantTitle.setAlignmentX(Component.CENTER_ALIGNMENT);

    add(grantTitle);
    frame.setVisible(true);
            delay(3);
            frame.dispose();
}

@Override
protected void paintComponent(Graphics g) {
    int w = getWidth(), h = getHeight();
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g;
    g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    GradientPaint gp = new GradientPaint(0, 0, Color.BLACK, 0, h, Color.GRAY);
    g2d.setPaint(gp);
    g2d.fillRect(0, 0, w, h);
}

    void delay (int sec){   
    try {
        TimeUnit.SECONDS.sleep(sec);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

So the problem with this (and every other type of technique I've tried, including nested FOR loops in an act of desperation..) is that the windows never appears.

Im assuming it's because the sleep is taking place before the frame.setVisible() can take effect. I've tried wait() also with the same effect.

Can anybody help me out on this one?

EDIT--

Here's how I've instantiated it (within another Class). The screen which precedes this goes green then launches the "Accepted" window.The program has 8 Classes otherwise I'd just throw the whole thing up. Point to note, I am getting an 'unused' warning on the instantiation, but I'm not sure why.

    void validCode() {
        color1 = Color.GREEN;
        color2 = Color.GREEN;
        repaint();
        GrantedPane granted = new GrantedPane();
    }
GhostCat
  • 137,827
  • 25
  • 176
  • 248
user3226170
  • 175
  • 1
  • 1
  • 14
  • 1
    have you tried `sleep()`? – Bill F May 28 '17 at 04:12
  • 1
    @user3226170 Have you tried a Thread with sleep()? – Enzokie May 28 '17 at 04:14
  • 1
    Suppose using `Thread` `sleep()` would be ideal. this [post](https://stackoverflow.com/questions/1036754/difference-between-wait-and-sleep) is good to refer. – Rajith Pemabandu May 28 '17 at 04:16
  • According to [TimeUnit documentation](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/TimeUnit.html#sleep(long)), it internally performs a Thread.sleep, so I don't think that is the problem. I think it is a problem with the Swing components. Something about how the JFrame is defined within the JPanel? It has been too long since I worked with Swing, so I'm not sure how this is supposed to be done anymore. That's where I'd start looking - I think your sleep logic is just fine! – pacifier21 May 28 '17 at 04:19
  • Sleep() does the same thing... – user3226170 May 28 '17 at 04:28
  • 3
    Please read [How do I ask a good question?](http://stackoverflow.com/help/how-to-ask) before attempting to ask more questions. –  May 28 '17 at 04:33
  • Is google not working for you? Please see [How do I ask a good question?](http://stackoverflow.com/help/how-to-ask) –  May 28 '17 at 04:54
  • 1
    *"So the problem with this (and every other type of technique I've tried, including nested FOR loops in an act of desperation..) is that the windows never appears."* - This because every solution you seem to have tried is blocking the EDT. See [Concurrency in Swing](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/) for more details and [How to use Swing Timers](http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html) for a typical solution – MadProgrammer May 28 '17 at 06:28
  • Yep the solution (which worked) was to use a Timer and an ActionListener. I'm still not 100% clear on how the EDT was getting blocked with the other methods, but I'm going to do some reading. Thanks for the help though all. – user3226170 May 29 '17 at 00:02

3 Answers3

2

Have you instantiated the class anywhere? Have added a main method and updated imports. Its working fine.

import java.util.concurrent.TimeUnit;
import java.awt.*;

import javax.swing.*;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;

public class GrantedPane extends JPanel {

private static final long serialVersionUID = 1L;

public GrantedPane() {

    JFrame frame = new JFrame();
    frame.setUndecorated(true);
    frame.setSize(400, 150);
    frame.setContentPane(this);
    frame.setLocationRelativeTo(null);
    frame.setSize(400, 80);

    setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
    setBorder(new CompoundBorder(BorderFactory.createLineBorder(Color.WHITE), new EmptyBorder(20, 20, 20, 20)));

    JLabel grantTitle = new JLabel(" Key Accepted ");
    grantTitle.setForeground(Color.YELLOW);
    grantTitle.setFont(new Font("Enter The Grid", Font.PLAIN, 32));
    grantTitle.setAlignmentX(Component.CENTER_ALIGNMENT);

    add(grantTitle);
    frame.setVisible(true);
    delay(3);
    frame.dispose();
}

@Override
protected void paintComponent(Graphics g) {
    int w = getWidth(), h = getHeight();
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g;
    g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    GradientPaint gp = new GradientPaint(0, 0, Color.BLACK, 0, h, Color.GRAY);
    g2d.setPaint(gp);
    g2d.fillRect(0, 0, w, h);
}

    void delay (int sec){

    try {
        TimeUnit.SECONDS.sleep(sec+2);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

    public static void main(String args[]){
        GrantedPane d = new GrantedPane();
    }
}
Rajeev Ranjan
  • 3,588
  • 6
  • 28
  • 52
  • Yes it works perfectly right up until I add `delay()`, then I get the issues. – user3226170 May 28 '17 at 04:30
  • 1
    Could you also share where you have intantiated this class? The code I shared is perfectly running with delays also(I tried changing the delays and got the correct results) – Rajeev Ranjan May 28 '17 at 04:32
  • @user3226170 You are getting the unused waring because you are not using the "granted" instance anywhere after creation. You reach the end of the function. – Rajeev Ranjan May 28 '17 at 05:18
  • Because `GrantedPane` is not been called been called within the contex of the `EDT`, you flucked not blocking the entire UI, a Swing `Timer` would generally be a safer solution – MadProgrammer May 28 '17 at 06:27
1

A non answer here: your idea does not make sense from a user experience side of things. Sure, it provides some learning to get this to work from a technical point of view. But besides that, you are wasting your time with such an approach.

Instead of automatically showing and dropping a frame, put up a modal option dialog for example. Simply ask the user to click a button when he is done reading.

You see, that is the problem with timeouts: you never get them right for all your users! If the delay is long enough so that 99 percent of the users could read the message, probably 50 percent will complain that your UI has them waiting too long. (the 1 percent being people getting distracted that never notice that self closing window).

And the last thing that you want: users that feel your application is slowing them down. There are well known best practices to present messages to users. Showing and dropping them automatically is not on that list of best practices.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
1

So the problem with this (and every other type of technique I've tried, including nested FOR loops in an act of desperation..) is that the windows never appears.

This because every solution you seem to have tried is blocking the EDT. See Concurrency in Swing for more details and How to use Swing Timers for a typical solution which is safe to user in Swing (won't block the EDT and can be used to safely update the UI)

import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;

public class GrantedPane extends JPanel {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new GrantedPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                Timer timer = new Timer(3000, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        frame.dispose();
                    }
                });
                timer.start();
            }
        });
    }

    private static final long serialVersionUID = 1L;

    public GrantedPane() {

        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
        setBorder(new CompoundBorder(BorderFactory.createLineBorder(Color.WHITE), new EmptyBorder(20, 20, 20, 20)));

        JLabel grantTitle = new JLabel(" Key Accepted ");
        grantTitle.setForeground(Color.YELLOW);
        grantTitle.setFont(new Font("Enter The Grid", Font.PLAIN, 32));
        grantTitle.setAlignmentX(Component.CENTER_ALIGNMENT);

        add(grantTitle);
    }

    @Override
    protected void paintComponent(Graphics g) {
        int w = getWidth(), h = getHeight();
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        GradientPaint gp = new GradientPaint(0, 0, Color.BLACK, 0, h, Color.GRAY);
        g2d.setPaint(gp);
        g2d.fillRect(0, 0, w, h);
    }

}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366