1

I am having some issues getting my GUI to exit on close. I have tried

frame.setDefaultCloseOperation(JFrame.CLOSE_ON_EXIT);

I have tried it with DISPOSE_ON_EXIT and it is not working.

when I run the program without any of that code and I click "X" it closes the window, but it is still running.

When I put that code in it will not compile and I get this error.

Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - Erroneous tree type: <any>
    at InvestmentFrame2.main(InvestmentFrame2.java:103)

I have tried reading suggestions on here as well as on other websites. The book I am using to learn this stuff didn't really explain anything about it, but just had it in some example code So I have just been trying some various suggestions.

I couldn't figure out if I maybe needed to import something else or if there is some other issue?

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class InvestmentFrame2 extends JFrame
{
    private static final int FRAME_WIDTH = 450;
    private static final int FRAME_HEIGHT = 250;

    private static final double DEFAULT_RATE = 0;
    private static final double INITIAL_BALANCE = 0;
    private static final double YEARS = 0;

    private JLabel rateLabel;
    private JLabel balanceLabel;
    private JLabel yearsLabel;

    private JTextField rateField;
    private JTextField balanceField;
    private JTextField yearsField;

    private JButton button;

    private JLabel resultLabel;
    private double balance;

    public InvestmentFrame2()
    {
        balance = INITIAL_BALANCE;
        resultLabel = new JLabel("Balance: " + balance);

        createTextField();
        createButton();
        createPanel();

        setSize(FRAME_WIDTH, FRAME_HEIGHT);
    }

    private void createTextField()
    {
        rateLabel = new JLabel("Interest Rate: ");
        balanceLabel = new JLabel("Account Balance: ");
        yearsLabel = new JLabel("Number of Years Saving: ");

        final int FIELD_WIDTH = 10;

        rateField = new JTextField(FIELD_WIDTH);
        rateField.setText ("" + DEFAULT_RATE);

        balanceField = new JTextField(FIELD_WIDTH);
        balanceField.setText("" + INITIAL_BALANCE);

        yearsField = new JTextField(FIELD_WIDTH);
        yearsField.setText("" + YEARS);
    }

    class AddInterestListener implements ActionListener
    {
        public void actionPerformed(ActionEvent event)
        {
            double rate = Double.parseDouble(rateField.getText());
            double accountBalance = Double.parseDouble(balanceField.getText());
            double years = Double.parseDouble(yearsField.getText());
            double interest = (accountBalance * rate / 100) * years;
            balance = accountBalance + interest;
            resultLabel.setText("Balance: " + balance);
        }
    }

    private void createButton()
    {
        button = new JButton("Calculate Balance");

        ActionListener listener = new AddInterestListener();
        button.addActionListener(listener);
    }

    private void createPanel()
    {
        JPanel panel = new JPanel();
        panel.add(rateLabel);
        panel.add(rateField);

        panel.add(balanceLabel);
        panel.add(balanceField);

        panel.add(yearsLabel);
        panel.add(yearsField);

        panel.add(button);
        panel.add(resultLabel);
        add(panel);
    }

    public static void main(String[] args)
    {
        JFrame frame = new InvestmentFrame2();
        frame.setTitle("Savings Frame");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_EXIT);
        frame.setVisible(true);
    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
twjohns29
  • 125
  • 4
  • 12
  • My IDE also gives a message before I run it that says it can't find the symbol CLOSE_ON_EXIT or DISPOSE_ON_EXIT? – twjohns29 Jul 28 '14 at 04:23

1 Answers1

4

You're trying to run a class which is uncompilable...JFrame.DISPOSE_ON_EXIT doesn't exist. You are actually looking for JFrame.EXIT_ON_CLOSE

Take a minute to read the JavaDocs for JFrame

public void setDefaultCloseOperation(int operation)

Sets the operation that will happen by default when the user initiates a "close" on this frame. You must specify one of the following choices:

* DO_NOTHING_ON_CLOSE (defined in WindowConstants): Don't do anything; require the program to handle the operation in the windowClosing method of a registered WindowListener object.
* HIDE_ON_CLOSE (defined in WindowConstants): Automatically hide the frame after invoking any registered WindowListener objects.
* DISPOSE_ON_CLOSE (defined in WindowConstants): Automatically hide and dispose the frame after invoking any registered WindowListener objects.
* EXIT_ON_CLOSE (defined in JFrame): Exit the application using the System exit method. Use this only in applications.

The value is set to HIDE_ON_CLOSE by default. Changes to the value of this property cause the firing of a property change event, with property name "defaultCloseOperation".

You might also find How to Make Frames (Main Windows) of some use...

You should also ensure that your UI is created within the context of the Event Dispatching Thread, take a look at Initial Threads for more details

Updated with example

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class InvestmentFrame2 extends JFrame {

    private static final int FRAME_WIDTH = 450;
    private static final int FRAME_HEIGHT = 250;

    private static final double DEFAULT_RATE = 0;
    private static final double INITIAL_BALANCE = 0;
    private static final double YEARS = 0;

    private JLabel rateLabel;
    private JLabel balanceLabel;
    private JLabel yearsLabel;

    private JTextField rateField;
    private JTextField balanceField;
    private JTextField yearsField;

    private JButton button;

    private JLabel resultLabel;
    private double balance;

    public InvestmentFrame2() {
        balance = INITIAL_BALANCE;
        resultLabel = new JLabel("Balance: " + balance);

        createTextField();
        createButton();
        createPanel();

        setSize(FRAME_WIDTH, FRAME_HEIGHT);
    }

    private void createTextField() {
        rateLabel = new JLabel("Interest Rate: ");
        balanceLabel = new JLabel("Account Balance: ");
        yearsLabel = new JLabel("Number of Years Saving: ");

        final int FIELD_WIDTH = 10;

        rateField = new JTextField(FIELD_WIDTH);
        rateField.setText("" + DEFAULT_RATE);

        balanceField = new JTextField(FIELD_WIDTH);
        balanceField.setText("" + INITIAL_BALANCE);

        yearsField = new JTextField(FIELD_WIDTH);
        yearsField.setText("" + YEARS);
    }

    class AddInterestListener implements ActionListener {

        public void actionPerformed(ActionEvent event) {
            double rate = Double.parseDouble(rateField.getText());
            double accountBalance = Double.parseDouble(balanceField.getText());
            double years = Double.parseDouble(yearsField.getText());
            double interest = (accountBalance * rate / 100) * years;
            balance = accountBalance + interest;
            resultLabel.setText("Balance: " + balance);
        }
    }

    private void createButton() {
        button = new JButton("Calculate Balance");

        ActionListener listener = new AddInterestListener();
        button.addActionListener(listener);
    }

    private void createPanel() {
        JPanel panel = new JPanel();
        panel.add(rateLabel);
        panel.add(rateField);

        panel.add(balanceLabel);
        panel.add(balanceField);

        panel.add(yearsLabel);
        panel.add(yearsField);

        panel.add(button);
        panel.add(resultLabel);
        add(panel);
    }

    public static void main(String[] args) {
        JFrame frame = new InvestmentFrame2();
        frame.setTitle("Savings Frame");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

Compiles and runs just fine for me...

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • 1
    I will check out those sources, but I initially tried it with EXIT_ON_CLOSE. and it still would not compile, so after reading some other questions on here i thought I would try the DISPOSE_ON_EXIT. – twjohns29 Jul 28 '14 at 04:18
  • @twjohns29 Really, compiled and run just fine for me...especially considering I've been using it since Java 1.3... – MadProgrammer Jul 28 '14 at 04:21
  • Well that is frustrating. I am using on NetBeans IDE 8.0. I'm not sure if that could have anything to do with it, but It gives a message in the text editor that it can't find the variable CLOSE_ON_EXIT. – twjohns29 Jul 28 '14 at 04:37
  • 1
    I would argue that **`DISPOSE_ON_CLOSE`** is the best way to go here. When the user closes the (last) window, the VM will end. See [this answer](http://stackoverflow.com/a/7143398/418556) for a demo that launches 3 frames. The VM will exit after the last frame is closed. – Andrew Thompson Jul 28 '14 at 06:20
  • @AndrewThompson That's a valid point but would require more context – MadProgrammer Jul 28 '14 at 06:23
  • @twjohns29 I updated, compiled and ran you example from Netbeans 8. It's not finding `CLOSE_ON_EXIT` because it's not a valid property...see the Java Docs for a list of valid properties... – MadProgrammer Jul 28 '14 at 06:25
  • The thing is, if the VM does **not** exit on window close, but keeps running, it indicates an application thread that should be cleaned up prior to exit. It might be something as harmless as a timer for an animation, but best track it down, and ensure it is accounted for one way or another. ..is the context I was thinking. ;) – Andrew Thompson Jul 28 '14 at 06:26
  • 1
    @AndrewThompson Not disagreeing, but (forbid) you have two windows open, you may want the "main" window to always exit the program, for example. But I agree, it's a great way of trapping renegade code ;) – MadProgrammer Jul 28 '14 at 06:27
  • *"but (forbid) you have two windows open, you may want the "main" window to always exit the program, for example."* Huh.. Hadn't thought of that. I usually design my apps with secondary top-level containers either being a full screen `JWindow` (that the user clicks, presses the esc key etc. to close) or modal dialogs that mean the user has to attend to them before proceeding. – Andrew Thompson Jul 28 '14 at 06:33
  • @AndrewThompson Yep, I prefer single "main" window concepts as well – MadProgrammer Jul 28 '14 at 06:39
  • got it EXIT_ON_CLOSE. Thanks – twjohns29 Jul 28 '14 at 23:52