1

I have a game that has a MainUI class, a GameClass and a SettingsClass. The game works fine except when I click "Restart" or "Help" which takes me to another JFrame and then returns back to the MainUI by a click of a button. But, when that happens, the MainUI class does not dispose of itself when it should. I believe it has to do with instantiating the MainUI class again when I leave and come back from settings but I'm but sure how to fix it.

This is the code I'm using to dispose of the MainUI frame and open a new JFrame:

private final JFrame mainFrame;
mainFrame.dispose(); //the mainFrame variable is passed in the constructor since it's trying to dispose of the MainUI
EndingPage endingPage = new EndingPage(); //open ending page
endingPage.setVisible(true);

This is an example of part of the code for one of the buttons in the settings class

restart.addMouseListener(new MouseAdapter() { 
    @Override
    public void mouseClicked(MouseEvent e) {
         MainUI.started=false;
         mainFrame.dispose();
         TitlePage title = new TitlePage();
         title.setVisible(true);
    }
});

When one of those buttons are clicked, another JFrame is opened accordingly. To go back to the MainUI this is run:

this.dispose();
MainUI main = new MainUI();
main.setVisible(true);

For more clarification, the second code is run when the user clicks the settings button. Then, the last code is run to get back to the JFrame it already was at. When the user wins the first code is run. But the issue is sometimes the mainFrame.dispose(); in the first code does not work. Any help is appreciated! If you need to see other code please tell me! I'm stuck.

EDIT: This is the MainUI (there is a timer because I want to delay before the action)

package stackoverflowcode;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;

public class MainUI extends javax.swing.JFrame {

    /**
     * Creates new form MainUI
     */
    public MainUI() {
        initComponents();
        GameClass game = new GameClass(this, end);
        SettingsClass settings = new SettingsClass(restart, this);
        
        Timer timer;
        private javax.swing.JButton end;
        private javax.swing.JButton restart;

        ActionListener action = new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent event)
            {
                game.openEnd();
            }
        };
        timer= new Timer (1000,action);
        timer.start();
        
        settings.settings();
        
    }
     private void initComponents() {

        restart = new javax.swing.JButton();
        end = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        restart.setText("SETTINGS");

        end.setText("END");
        javax.swing.GroupLayout layout = new 
        javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(151, 151, 151)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(end)
                    .addComponent(restart))
                .addContainerGap(168, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(120, 120, 120)
                .addComponent(restart)
                .addGap(48, 48, 48)
                .addComponent(end)
                .addContainerGap(86, Short.MAX_VALUE))
        );

        pack();
     }
public static void main(String args[]) {
    java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new MainUI().setVisible(true);
            }
        });
    }                 
}

SettingsClass

package stackoverflowcode;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;

public class SettingsClass {
    JButton restart;
    JFrame mainFrame;
    
    public SettingsClass(JButton restart, JFrame mainFrame){
        this.restart=restart;
        this.mainFrame=mainFrame;
    }

public void settings() {
        restart.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                mainFrame.dispose();
                TitlePage title = new TitlePage();
                title.setVisible(true);
            }
        });
    }

}

TitlePage

package stackoverflowcode;
public class TitlePage extends javax.swing.JFrame {

    /**
     * Creates new form TitlePage
     */
    public TitlePage() {
        initComponents();
        private javax.swing.JButton Play;
    }
    private void initComponents() {

        Play = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        Play.setText("PLAY");
        Play.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                PlayActionPerformed(evt);
            }
        });
        javax.swing.GroupLayout layout = new 
        javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(134, 134, 134)
                .addComponent(Play)
                .addContainerGap(209, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(129, 129, 129)
                .addComponent(Play)
                .addContainerGap(148, Short.MAX_VALUE))
        );

        pack();
    }
    private void PlayActionPerformed(java.awt.event.ActionEvent evt) {                                     
        // TODO add your handling code here:
        this.dispose();
        MainUI main = new MainUI();
        main.setVisible(true);
    }  
    public static void main(String args[]){
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new TitlePage().setVisible(true);
            }
        });
    }
}   

GameClass

package stackoverflowcode;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;

public class GameClass {
    private final JFrame mainFrame;
    private final JButton endButton;
    
    public GameClass(JFrame mainFrame, JButton endButton){
        this.mainFrame=mainFrame;
        this.endButton=endButton;
    }
    
    public void openEnd(){
        endButton.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                mainFrame.dispose(); //the mainFrame variable is passed in the constructor since it's trying to dispose of the MainUI
                TitlePage endingPage = new TitlePage(); //open title page
                endingPage.setVisible(true);
            }
        });
        
    }
}
iz1212
  • 11
  • 3
  • 1
    Instead of creating / disposing multiple JFrames, which creates a terrible user experience, it would be better to either 1) Use CardLayout, [for example](https://stackoverflow.com/a/54043710/2180785) and [for example](https://stackoverflow.com/a/49519023/2180785), or use Dialogs, [for example](https://stackoverflow.com/a/41904856/2180785), or combine them both [for example](https://stackoverflow.com/a/63121986/2180785) – Frakcool Jan 11 '21 at 23:04
  • Thank you for answering! But I already have many JFrames. Is there a way to fix my problem as it is or convert the JFrames or JPanels into a CardLayout? Sorry I've never used CardLayout I'm not entirely sure how it works. – iz1212 Jan 11 '21 at 23:14
  • Without a proper [mre] I think it's really hard to help you, you mention you pass the frame's instance in the parameter, probably, somewhere you're creating another instance from it – Frakcool Jan 11 '21 at 23:16
  • Hi I added a minimal reproducible example that I hope is enough! Although now I'm thinking there might be something wrong with the timer instead of the instantiation. Is there any way you can help now? – iz1212 Jan 12 '21 at 00:38
  • 1
    There's no `main` method, that's still not a proper [mre] – Frakcool Jan 12 '21 at 00:50
  • Omg I accidentally deleted the main method when adjusting the code to update the question I'm so sorry for the inconvenience. I hope it's ok now? – iz1212 Jan 12 '21 at 00:55
  • 1
    Where are you adding the buttons to the frames? Please create a brand new project, where you can compile and run all 4 classes (if possible reduce them to 1-2 maximum), and where your issue is still reproducible. Also if your classes are basically in constructor structure, keep the buttons / frames references to them in the same order – Frakcool Jan 12 '21 at 01:01
  • Netbeans has a lot of generated code for GUI so I was a little confused what to add and what not to but I added the generated code that I believe adds the buttons to the frames I hope this helps (sorry there are so many issues this is my first time posting a question.) :( – iz1212 Jan 12 '21 at 01:19
  • 2
    At least you're being open to criticism and are actually providing the needed information. Instead of having the GUI generated by netbeans, the best way to do it is "by hand" where you have control over the code and not the IDE, I wouldn't be able to run it in Eclipse or IntelliJ if you gave it to me (and those are the IDEs that I use the most, I quit netbeans long ago). What's the actual layout manager that netbeans is using? Look for `setLayout` or just `layout` – Frakcool Jan 12 '21 at 01:51
  • Ok I understand thank you! I added some code that has to do with the layout I hope this helps. – iz1212 Jan 12 '21 at 03:01
  • OH WAIT I think I just fixed it somehow by myself. Thank you anyways even though it may not seem like you helped much you still helped me learn more about my code and how to form a proper question! – iz1212 Jan 12 '21 at 03:16
  • Glad I was of any help, keep up the good work and for your next program try using JPanels rather than JFrames so that your code is easier to modify and implement CardLayout / use Dialogs next time. It'll improve your code big time – Frakcool Jan 12 '21 at 04:09

0 Answers0