I am just now learning the basics of java GUI. I have this weird situation that I can’t really explain.
I have a GUI class, where I build a simple JFrame. If I use .setVisible(true) within the constructor everything works fine, if I use it outside, nothing loads (the window is visible, but the buttons and what not aren’t).
Why is this happening ?
public class GUI extends JFrame {
private JTextField humanYears_TextField = new JTextField(3);
private JTextField dogYears_TextField = new JTextField(3);
private JButton convert_Button = new JButton("Convert");
private JLabel greeting = new JLabel ("Dog years to Human years!");
public GUI () {
JFrame window = new JFrame();
JPanel content = new JPanel();
content.setLayout(new FlowLayout());
content.add(this.greeting);
content.add(new JLabel("Dog Years: "));
content.add(this.dogYears_TextField);
content.add(this.convert_Button);
content.add(new JLabel("Human Years: "));
content.add(this.humanYears_TextField);
window.setContentPane(content);
pack(); // aplica contentPane-ul
window.setLocationRelativeTo(null);
window.setTitle("Dog Year Converter");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true); // IF IT'S HERE IT WORKS
}
}
public static void main(String[] args) {
GUI dogYears = new GUI();
//dogYears.setVisible(true); // IF IT'S HERE
//NOTHING EXCEPT THE WINDOW LOADS
}
Why is this happening ?
In this example it doesn’t matter, but what if I want to make a window visible only if I click a button or something ?
1) You create 2 instances of
JFramethe first from extendingJFrameon the class and the second fromJFrame window=... You than go on to callsetVisible(..)on thewindowand in your main you attempt to callsetVisible(...)on yourdogYears.Solution
You should only create one
JFrameper Swing GUI. Get rid of theextends JFrame(and the code that goes with it), as its not good practice to extendJFramein Swing. Thus of course you wont be able to callsetVisible(true)in your constructor which is fine either call it after creating the GUI in the constructor or make a method likesetVisiblein GUI class which will be a wrapper for yourJFramessetVisble(boolean b)method.Other suggestions
Always create your Swing components on the
Event Dispatch Threadwhich you should do in viaSwingUtilitites.invokeLater(Runnable r)block. Have a read on Concurrency in Swing.Remember to call pack before setting
JFramevisible and after adding components.setLocationRelativeTo(..)should come afterpack().Better to use
JFrame.DISPOSE_ON_CLOSEunless using Timers.Also no need for
setContentPanesimply calladd(..)onJFrameinstance.Here is your code with above mentioned fixes: