0

So I tried searching and I found an answer here: Java swing application, close one window and open another when button is clicked

I did the example given there and it worked just fine. But when I tried to put it in my code it's not working.

The objective of my program is to open a new window when a button is clicked. The program shows an error when dispose() is there but it still won't run when it's deleted. Is there any way to fix this? Or should I try using CardLayout? Thanks in advance.

Here's my code:

HelpME.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class HelpME extends JPanel 
                implements ActionListener{

private JButton PetrolStation=new JButton("Petrol Stations");
private JButton Food=new JButton("Foods");
private JButton Parking=new JButton("Parkings");
private JButton Coffee=new JButton ("Coffee");
private JButton Shopping=new JButton("Shoppings");
private JButton Pharmacies=new JButton("Pharmacies");
private JButton Supermarket=new JButton ("Supermarkets");
private JButton Hospital=new JButton ("Hospitals");
private JButton Hotel=new JButton ("Hotels");
private JButton OutdoorPark=new JButton ("Outdoor Parks");

public HelpME(){

    HelpME h = new HelpME();
    h.setLayout(new GridLayout(5,2));

    JFrame f = new JFrame("HelpMe");
    f.getContentPane().add(h);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setSize(460, 460);
    f.setVisible(true);   
    f.setLocationRelativeTo(null);

    PetrolStation.addActionListener(this);
    Food.addActionListener(this);
    Food.setActionCommand("Foods");
    Parking.addActionListener(this);
    Coffee.addActionListener(this);
    Shopping.addActionListener(this);
    Pharmacies.addActionListener(this);
    Supermarket.addActionListener(this);
    Hospital.addActionListener(this);
    Hotel.addActionListener(this);
    OutdoorPark.addActionListener(this);

    add(PetrolStation);
    add(Food);
    add(Parking);
    add(Coffee);
    add(Shopping);
    add(Pharmacies);
    add(Supermarket);
    add(Hospital);
    add(Hotel);
    add(OutdoorPark);

}

@Override
public void actionPerformed(ActionEvent e) {
    String cmd = e.getActionCommand();

    if(cmd.equals("Foods"))
    {
        dispose();
        new SecondScreen();
    }

}

public static void main(String[] args) {

    SwingUtilities.invokeLater(new Runnable(){

        @Override
        public void run()
        {
            new HelpME().setVisible(true);
        }

    });
}

}

SecondScreen.Java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class SecondScreen extends JFrame {

public SecondScreen() {
    super("Location Finder");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    add(new JLabel("Empty JFrame"));
    pack();
    setVisible(true);
}
}

This is the error

Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at java.lang.ReflectiveOperationException.<init>(ReflectiveOperationException.java:89)
at java.lang.reflect.InvocationTargetException.<init>(InvocationTargetException.java:72)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javax.swing.UIDefaults.getUI(UIDefaults.java:769)
at javax.swing.UIManager.getUI(UIManager.java:1016)
at javax.swing.JPanel.updateUI(JPanel.java:126)
at javax.swing.JPanel.<init>(JPanel.java:86)
at javax.swing.JPanel.<init>(JPanel.java:109)
at javax.swing.JPanel.<init>(JPanel.java:117)
at HelpME.<init>(HelpME.java:19)
at HelpME.<init>(HelpME.java:21)
at HelpME.<init>(HelpME.java:21)
at HelpME.<init>(HelpME.java:21)
at HelpME.<init>(HelpME.java:21)
at HelpME.<init>(HelpME.java:21)
at HelpME.<init>(HelpME.java:21)

This is how my first window should look like

Community
  • 1
  • 1
Farhan
  • 11
  • 1
  • 7

1 Answers1

4

Your constructor is inexplicably recursive:

public HelpME(){

    HelpME h = new HelpME();
    ...
}

Every time you you try it instantiate it, it will try to instantiate another one, which will try to instantiate another one, which will try to instantiate another one .... until your stack overflows.

You certainly want to get rid of

HelpME h = new HelpME();

and should probably change

h.setLayout(new GridLayout(5,2));

to

setLayout(new GridLayout(5,2));
bradimus
  • 2,472
  • 1
  • 16
  • 23
  • Is there anything I can do? I'm not so good in this so I don't really understand what to do – Farhan May 11 '17 at 16:31
  • Did that but dispose() still shows error. They say "the method dispose() is undefined for the type HelpME" – Farhan May 11 '17 at 16:45
  • @Farhan That would be because `HelpME` extends `JPanel` and [`JPanel` does not expose a method `dispose()`](https://docs.oracle.com/javase/8/docs/api/javax/swing/JPanel.html). You might consider extending [`JFrame`](https://docs.oracle.com/javase/8/docs/api/javax/swing/JFrame.html) instead or using using [`SwingUtilities.getWindowAncestor(this).dispose()`](https://docs.oracle.com/javase/8/docs/api/javax/swing/SwingUtilities.html#getWindowAncestor-java.awt.Component-). I don't know your requirements, so you will have to work it out. – bradimus May 11 '17 at 16:58
  • 1
    @Frakcool That would work, but `f` would need to be made in scope in the listener. – bradimus May 11 '17 at 17:02
  • True, as a class member maybe ^^ – Frakcool May 11 '17 at 17:11
  • I've added a picture of how my window should look like @Frakcool – Farhan May 11 '17 at 17:13
  • The error has been pointed out, it should be solved by making use of what was said in this answer... If that doesn't solve your question edit it accordingly inlcuding a [mcve] with 1 or 2 buttons where it demonstrates your issue... – Frakcool May 11 '17 at 17:15