Java JFrame GUI not showing anything other than title....

  • Thread starter Thread starter Wrichik Basu
  • Start date Start date
  • Tags Tags
    Gui
AI Thread Summary
The discussion revolves around a Java Swing program that launches multiple JFrame windows based on user input, with a specific focus on the function makeGUI_4(). The issue arises when the JFrame intended to display error messages does not show the JLabels as expected. The problem is traced to the use of Thread.sleep() immediately after setting the JFrame visible, which causes the window to disappear before it can be seen. To resolve this, it is suggested to use a Timer instead of sleeping the thread. The Timer allows for asynchronous execution, enabling the window to remain visible for a specified duration before calling makeGUI_2() to transition to the next window. The correct approach involves creating the JFrame, adding components, and then using a Timer to manage the visibility duration without blocking the event dispatch thread. This highlights the importance of understanding event-driven programming in Java Swing to ensure proper GUI behavior.
Wrichik Basu
Science Advisor
Insights Author
Gold Member
Messages
2,180
Reaction score
2,717
I have written a program that will launch three JFrame windows if the user enters the correct things everywhere. In case there is a mistake, an error window will open, and then after 3s, the user will be re-directed to the window where he made the error.

The flowchart is attached.

Everything is working fine except the JFrame created by makeGUI_4().

The function makeGUI_4() looks something like this:
Java:
private void makeGUI_4() {
        try {
            jfrm4 = new JFrame();
            jfrm4.setLayout(new FlowLayout());
            jfrm4.setBounds(50, 50, 527, 351);
            jfrm4.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            jfrm4.setTitle("Error!");
            
            jlb1 = new JLabel("Wrong date/time.");
            jlb2 = new JLabel("Program restarting...");
            jfrm4.add(jlb1);
            jfrm4.add(jlb2);
            jfrm4.setVisible(true);
            Thread.sleep(3000);
            jfrm4.setVisible(false);
            makeGUI_2();
            
        } catch (InterruptedException ex) {
            Logger.getLogger(BuildGUI.class.getName()).log(Level.SEVERE, null, ex);
        }
 }
Here, jlb1 and jlb2 are two JLabels declared as class variables. jfrm4 is a JFrame also declared as a class variable.

I want a simple window that shows:
"Wrong date/time."
"Program restarting..."
and then the thread goes to sleep for 3s, and calls makeGUI_2().

This is what I get when the user makes an error and makeGUI_4() is called:

1569257887725.png


The JLabels just don't appear in the window.

Where am I going wrong?
 

Attachments

Technology news on Phys.org
Could this be a race condition? The code I've seen used an invokeLater() setup to allow the GUI to get created before its displayed. Also pack() and setVisible(true) is usually the very last thing you do.

Can you run this via a debugger like use NetBeans and its debugger?

Here's an example of EventQueue.invokeLater() usage:

http://referencedesigner.com/tutorials/javaswing/javaswing_02.php
and a nice presentation of HelloWorld but without invokeLater

https://www.javaguides.net/2019/06/java-swing-hello-world-example-tutorial.html
https://www.codejava.net/java-se/sw...orld-tutorial-for-beginners-using-text-editor
Also I found this site with lots of examples though none are using invokeLater but might be useful in your other programs:

https://javacodex.com/Swing/Hello-World
 
jedishrfu said:
Could this be a race condition? The code I've seen used an invokeLater() setup to allow the GUI to get created before its displayed.
I am not quite sure where to add the invokeLater(). I added it to the function call of makeGUI() (the first function being called), and there is no change. I added it to the function call of makeGUI_4() by changing the code in makeGUI_3() to this:
Java:
SwingUtilities.invokeLater(new Runnable(){
    @Override
    public void run(){
        makeGUI_4();
    }
});
but there is still no luck.
jedishrfu said:
Can you run this via a debugger like use NetBeans and its debugger?
I am using Apache NetBeans 11.0 with JDK 12. Note that the build always completes successfully, even if the window is not displayed correctly. How do I use the debugger here?

I did some debugging myself and found that if I comment out the last parts of the function and change it to:
[CODE lang="java" title="Function makeGUI_4()" highlight="19-20"]private void makeGUI_4() {

jfrm4 = new JFrame();
jfrm4.setLayout(new FlowLayout());
jfrm4.setBounds(50, 50, 527, 351);
jfrm4.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jfrm4.setTitle("Error!");

jlb1 = new JLabel("Wrong date/time.");
jlb2 = new JLabel("Program restarting...");
jfrm4.add(jlb1);
jfrm4.add(jlb2);
jfrm4.setVisible(true);
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
Logger.getLogger(BuildGUI.class.getName()).log(Level.SEVERE, null, ex);
}
//jfrm4.setVisible(false);
//makeGUI_2();

}[/CODE]then the window is created properly. It seems that the problem is occurring when I am calling makeGUI_2()
 
Last edited:
It's been a while, but I think instead of
Java:
            jfrm4.add(jlb1);
            jfrm4.add(jlb2);
You want
Java:
            jfrm4.getContentPane().add(jlb1);
            jfrm4.getContentPane().add(jlb2);
and I think this might work as well
Java:
            jfrm4.setRootCheckingEnabled(true);
            jfrm4.add(jlb1);
            jfrm4.add(jlb2);
But like I say, it has been a while since I did any Java, especially Swing.
 
I found out the error. It is a simple logical error.

As @jedishrfu said, jfrm4.setVisible(true) is being executed at the end. As a result, the window is being created after a delay of 3s, but as soon as the window is created, the next command, jfrm4.setVisible(false) is executed, and the window vanishes. Hence, I was being unable to see the output. Commenting out the last code solved the problem.

Basically I wanted the window to stay for 3s before disappearing, and that's why I put the Thread.sleep() after setVisible(true). Let's see how I can do that now.

Update:

This can be done in the following way:
[CODE lang="java" title="Edited version of function makeGUI_4()" highlight="15-37"]private void makeGUI_4() {

jfrm4 = new JFrame();
jfrm4.setLayout(new FlowLayout());
jfrm4.setBounds(50, 50, 527, 351);
jfrm4.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jfrm4.setTitle("Error!");

jlb1 = new JLabel("Wrong date/time.");
jlb2 = new JLabel("Program restarting...");
jfrm4.add(jlb1);
jfrm4.add(jlb2);
jfrm4.setVisible(true);

Timer timer = new Timer(1000, new ActionListener() {
int i = 0;

@Override
public void actionPerformed(ActionEvent ae) {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(BuildGUI.class.getName()).log(Level.SEVERE, null, ex);
}
i++;
if (i == 3) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
jfrm4.setVisible(false);
makeGUI_2();
}
});
}
}
});
timer.start();

}[/CODE]
 
Last edited:
You can not create the JFrame, add stuff to it, then sleep all in a row. Here is what is happening in order:

Create JFrame, which creates an actual window in Windows and sets it up.
You add two Labels to the object, which causes a repaint event to go into the event queue
You then sleep in your thread
Your method returns and goes back into the event loop which then gets the queued repaint event, which then draws

You're expecting the setVisible to be a synchronous function that will instantly show you the state of the window, but that's now how these windows work, they're almost entirely event driver and you are IN the event loop when you create this window.

You need to get your head around event driven code. You'll need this in order to have the window stick around for three seconds, you don't want to stop your UI thread for stuff like that, you want to register a timeout event, which then calls a function to dispose of your window.
 
  • Like
Likes Wrichik Basu
I tried a web search "the loss of programming ", and found an article saying that all aspects of writing, developing, and testing software programs will one day all be handled through artificial intelligence. One must wonder then, who is responsible. WHO is responsible for any problems, bugs, deficiencies, or whatever malfunctions which the programs make their users endure? Things may work wrong however the "wrong" happens. AI needs to fix the problems for the users. Any way to...

Similar threads

Replies
6
Views
3K
Replies
6
Views
3K
Replies
2
Views
4K
Replies
3
Views
13K
Back
Top