Using .setVisible () outside the constructor breaks my GUI

I am just learning the basics of the java GUI. I have such a strange situation that I can’t explain.

I have a GUI class where I build a simple JFrame. If I use .setVisible(true) inside the constructor , everything works fine, if I use it outside , nothing loads (the window is visible, but the buttons and what are not).

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 HERE IT WORKS } } public static void main(String[] args) { GUI dogYears = new GUI(); //dogYears.setVisible(true); // IF IT HERE //NOTHING EXCEPT THE WINDOW LOADS } 

Why is this happening?

In this example, it does not matter, but what if I want to make the window visible only if I press a button or something else?

+4
source share
5 answers

1) You create 2 JFrame instances for the first of the JFrame extensions for the class, and the second of the JFrame window=.. You, instead of saying setVisible(..) on window and in your main part you are trying to call setVisible(...) on dogYears .

Decision

You must create only one JFrame for each Swing GUI. Get extends JFrame (and the code that comes with it) as its not a good practice to extend JFrame in Swing. This way, of course, you cannot call setVisible(true) in your constructor, which calls it great after creating the GUI in the constructor, or creates a method like setVisible in a GUI class that will be a wrapper for your JFrame setVisble(boolean b) .

Other offers

  • Always create Swing components on the Event Dispatch Thread , which you must do with the SwingUtilitites.invokeLater(Runnable r) block. Read Concurrency in Swing .

  • Remember to make the package visible before installing the JFrame and after adding the components.

  • setLocationRelativeTo(..) should appear after pack() .

  • It is better to use JFrame.DISPOSE_ON_CLOSE if you do not use timers.

  • Also, there is no need for setContentPane just call add(..) on the JFrame instance.

Here is your code with the above fixes:

enter image description here

 import java.awt.FlowLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingUtilities; public class GUI { 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!"); private JFrame window = new JFrame(); private JPanel content = new JPanel(); public GUI() { 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.add(content); window.setTitle("Dog Year Converter"); window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); window.pack(); window.setLocationRelativeTo(null); //window.setVisible(true); //works here now } //our wrapper method so we can change visibility of our frame from outside the class void setVisible(boolean visible) { window.setVisible(visible); } public static void main(String[] args) { //Create Swing components on EDT SwingUtilities.invokeLater(new Runnable() { @Override public void run() { GUI dogYears = new GUI(); dogYears.setVisible(true);//works here too } }); } } 
+6
source

You have two JFrame s, the GUI class itself and the internal variable "window". Use only one.

Make sure that the GUI does not extend the JFrame (there is no need there), and give the class the public method void setVisible(boolean) , which sets the visible window.

 public class GUI { 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!"); private JFrame window = new JFrame(); public GUI () { 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 HERE IT WORKS } public void setVisible(boolean visible) { window.setVisible(visible); } } 
+5
source

You have two different instances :-)

in your constructor:

 JFrame window = new JFrame(); window.setVisible(true); // IF IT HERE IT WORKS 

mostly:

 GUI dogYears = new GUI(); dogYears.setVisible(true); // dogYears != local var window in constructor 

Which can make me start by not extending classes, but using them.

+4
source

Your GUI class extends from JFrame , but in the constructor you initialize another JFrame, which results in two different JFrame s .

Try the following:

 public class GUI { 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); } // main } 
+2
source

you create a JFrame instance in the GUI constructor, which also extends JFRame. Now you create different components and add them to the window object. As you know, the frame is set as visible = false and undecorated = false. Therefore, to install a specific JFrame instance, you need to call the setVisible () method on that instance.

Here you simply create an instance of the GUI and have not added any component to it. write the statement in the constructor as the following, and not "window.setContentPane (content);" :

setContentPane (content);

and then call the setVisible () method on your instance of the GUI class ie d * ogYears.setVisible (true); * !!

0
source

All Articles