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

  • Context: Java 
  • Thread starter Thread starter Wrichik Basu
  • Start date Start date
  • Tags Tags
    Gui
Click For Summary

Discussion Overview

The discussion revolves around a Java Swing application where a JFrame window is not displaying its components as expected. Participants explore potential causes, including threading issues and GUI event handling, while suggesting various coding approaches to resolve the problem.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Exploratory

Main Points Raised

  • One participant describes their implementation of a JFrame that should display error messages but fails to show the JLabels when invoked.
  • Another participant suggests that a race condition might be occurring and recommends using invokeLater() to ensure the GUI is created before being displayed.
  • A different participant attempts to implement invokeLater() but reports no change in behavior, indicating a potential misunderstanding of where to apply it.
  • One participant proposes that using getContentPane().add() instead of add() might resolve the issue, though they express uncertainty due to a lack of recent experience with Java Swing.
  • Another participant identifies a logical error in the original code, explaining that the JFrame becomes invisible immediately after being displayed due to the order of operations, suggesting a need for a timer instead of Thread.sleep().
  • A later reply emphasizes the importance of understanding event-driven programming in Swing, explaining that sleeping the thread disrupts the event queue and suggests using a Timer for delayed actions instead.

Areas of Agreement / Disagreement

Participants express differing views on the cause of the issue, with some attributing it to threading and event handling, while others focus on logical errors in the code. No consensus is reached on a single solution, as multiple approaches are discussed.

Contextual Notes

Limitations include the potential misunderstanding of event-driven programming in Swing and the implications of using Thread.sleep() within the GUI thread, which may lead to unresponsive behavior.

Wrichik Basu
Science Advisor
Insights Author
Gold Member
Messages
2,188
Reaction score
2,694
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   Reactions: Wrichik Basu

Similar threads

  • · Replies 6 ·
Replies
6
Views
3K
  • · Replies 6 ·
Replies
6
Views
3K
  • · Replies 2 ·
Replies
2
Views
5K
  • · Replies 2 ·
Replies
2
Views
4K
  • · Replies 3 ·
Replies
3
Views
13K