javanumero javanumero - 14 days ago 7
Java Question

Can't get Jframe to close when user hits (X)

I cannot get my Jframe to close when a user hits the (X) button. I tried many ways to do them but none of them work.

I tried:

JFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


Nothing happens. My main class extends jframe and implements action listener. What am I doing wrong?

My code:

package com.xflare.Bot;

import static java.lang.System.out;
import java.awt.*;
import java.lang.String;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
import javax.swing.JFrame;

public class Main extends JFrame implements ActionListener{

private static Frame frame;

private static boolean debug = true;

private static boolean enabled = true;

private static JButton exitbutton; // reference to the button object

private static JButton webbutton; // reference to the button object

private static JButton aboutbutton; // reference to the button object

public static void main(String[] args) {
new Main().start();
}

private void start(){
//start up
printSystem("starting");

//create frame
printSystem("Creating a frame...");
createFrame();

//create button(s)
createQuitButton();
createWebButton();
createAboutButton();

//Spawn init.
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getFrame().setResizable(false);
getFrame().setVisible(true);
printSystem("Started up successfully!");
}

private void createFrame(){
Main.frame = new Frame("app");
frame.setSize(600, 300);
}

private void createQuitButton(){
exitbutton = new JButton("Exit!");
getFrame().setLayout(null);
exitbutton.setBounds(225,45,150,75);//setBounds(x,y,width,height)
exitbutton.setActionCommand("exit");
exitbutton.addActionListener(this);
getFrame().add(exitbutton);
}

private void createWebButton(){
webbutton = new JButton("Open hacked browser");
getFrame().setLayout(null);
webbutton.setBounds(225,130,150,75);//setBounds(x,y,width,height)
webbutton.setActionCommand("web");
webbutton.addActionListener(this);
getFrame().add(webbutton);
}

private void createAboutButton(){
aboutbutton = new JButton("About");
getFrame().setLayout(null);
aboutbutton.setBounds(225,215,150,75);//setBounds(x,y,width,height)
aboutbutton.setActionCommand("about");
aboutbutton.addActionListener(this);
getFrame().add(aboutbutton);
}

private Frame getFrame(){
return Main.frame;
}

public void actionPerformed(ActionEvent e) {
String actionCommand = ((JButton) e.getSource()).getActionCommand();
printDebug("Button " + actionCommand + " was pressed.");
if(actionCommand.equals("exit")){
exitbutton.setVisible(false);
shutdown();
}
else if(actionCommand.equals("about")){
aboutbutton.setVisible(false);
webbutton.setVisible(false);
exitbutton.setVisible(false);
showAbout();
}
else{
printCritical("Unknown button pressed!");
}
}

private void showAbout(){

}

private void shutdown(){
printSystem("Attempting to shut down...");
enabled = false;
printSystem("Shut down successful!");
System.exit(0);
}

private boolean debugEnabled(){
return debug;
}

private String getVersion(){
return "1.0.0";
}

private String getCodename(){
return "[BeastReleased]";
}

private static void printSystem(String var){
out.println("System> " + var);
}

private static void printError(String var){
out.println("Error> " + var);
}

private static void printCritical(String var){
out.println("Critical> " + var);
}

private void printDebug(String var){
if(debugEnabled()) {
out.println("Debug> " + var);
}
}

}


Link to same code: http://pastebin.com/1fDbjm74

Answer

This: setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

needs to be called on the JFrame that you're actually displaying, Main.frame. You're not doing this.

getFrame().setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getFrame().setVisible(true);

You've got too many Frame / JFrames. Your class extends JFrame but you're not displaying it. You've also got a Frame variable called frame, (NOT a JFrame variable) that you are displaying, and of course since this is not a JFrame, you can't make JFrame method calls, like the one above on it.

Simplify: create ONE JFrame not a Frame, and call this method on it and set it visible. So either get rid of the frame variable and use the class itself, the this, as your JFrame, and display it, or don't have your class extend JFrame and use your frame variable, but make it a JFrame object not a Frame object, since Frame does not have the setDefaultCloseOperation(...) method.

Also you're over-using static modifiers where they shouldn't be used. All your fields should be instance (non-static) fields.

Also, use of null layouts and setBounds will bite you in the end. For instance when I run your program, portions of the middle button's text are missing because its size has been artificially constrained in a bad way. Much better is to us layout managers to your advantage. For example:....

Please have a look at this program structure:

import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.*;

public class MyMain extends JPanel {
    public static final String MENU_PANEL = "MENU";
    public static final String ABOUT_PANEL = "About";
    private CardLayout cardLayout = new CardLayout();

    public MyMain() {
        JPanel aboutPanel = new JPanel(new GridBagLayout());
        JLabel aboutLabel = new JLabel("About");
        aboutLabel.setFont(aboutLabel.getFont().deriveFont(Font.BOLD, 32));
        aboutPanel.add(aboutLabel);

        JPanel buttonPanel = new JPanel(new GridLayout(0, 1, 10, 10));
        buttonPanel.add(createButton(new ExitAction("Exit!", KeyEvent.VK_X)));
        buttonPanel.add(createButton(new OpenBrowserAction("Open Hacked Browser", KeyEvent.VK_O)));
        buttonPanel.add(createButton(new AboutAction("About", KeyEvent.VK_A, this)));        

        JPanel menuPanel = new JPanel(new GridBagLayout());
        int ebGap = 40;
        menuPanel.setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
        menuPanel.add(buttonPanel);

        setLayout(cardLayout);
        add(menuPanel, MENU_PANEL);
        add(aboutPanel, ABOUT_PANEL);
    }

    private JButton createButton(Action action) {
        JButton button = new JButton(action);
        Font btnFont = button.getFont().deriveFont(Font.BOLD, 20);
        button.setFont(btnFont);
        return button;
    }

    private static void createAndShowGui() {
        JFrame frame = new JFrame("My Main Application");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new MyMain());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

    public void showPanel(String cardLayoutKey) {
        cardLayout.show(this, cardLayoutKey);
    }
}

class ExitAction extends AbstractAction {
    public ExitAction(String name, int mnemonic) {
        super(name);
        putValue(MNEMONIC_KEY, mnemonic);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Component comp = (Component) e.getSource();
        if (comp != null) {
            Window win = SwingUtilities.getWindowAncestor(comp);
            if (win != null) {
                win.dispose();
            }
        }
    }
}

class OpenBrowserAction extends AbstractAction {
    public OpenBrowserAction(String name, int mnemonic) {
        super(name);
        putValue(MNEMONIC_KEY, mnemonic);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("Open Browswer");
    }
}

class AboutAction extends AbstractAction {
    private MyMain myMain;

    public AboutAction(String name, int mnemonic, MyMain myMain) {
        super(name);
        putValue(MNEMONIC_KEY, mnemonic);
        this.myMain = myMain;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (myMain != null) {
            myMain.showPanel(MyMain.ABOUT_PANEL);
        }
    }
}
Comments