【问题标题】:How to close my program when exiting the frame退出框架时如何关闭我的程序
【发布时间】:2014-07-28 12:22:36
【问题描述】:

我在关闭 GUI 时遇到了一些问题。我试过了

frame.setDefaultCloseOperation(JFrame.CLOSE_ON_EXIT);

我已尝试使用 DISPOSE_ON_EXIT,但无法正常工作。

当我在没有任何代码的情况下运行程序并单击“X”时,它会关闭窗口,但它仍在运行。

当我将该代码放入其中时,它将无法编译,并且出现此错误。

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

我已尝试阅读此处以及其他网站上的建议。我用来学习这些东西的书并没有真正解释它的任何内容,只是在一些示例代码中提供了它所以我一直在尝试一些不同的建议。

我不知道是否需要导入其他内容或是否存在其他问题?

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);
    }
}

【问题讨论】:

  • 我的 IDE 在我运行它之前也会给出一条消息,说它找不到符号 CLOSE_ON_EXIT 或 DISPOSE_ON_EXIT?

标签: java swing jframe


【解决方案1】:

您正在尝试运行一个不可编译的类...JFrame.DISPOSE_ON_EXIT 不存在。你其实是在找JFrame.EXIT_ON_CLOSE

花一点时间阅读JavaDocs for JFrame

public void setDefaultCloseOperation(int operation)

设置 当用户启动一个默认操作 在这个框架上“关闭”。您必须指定以下其中一项 选择:

* DO_NOTHING_ON_CLOSE(在 WindowConstants 中定义): 什么都不做;要求程序处理 已注册的 WindowListener 对象的 windowClosing 方法。
* HIDE_ON_CLOSE(在 WindowConstants 中定义):自动隐藏 调用任何已注册的 WindowListener 对象后的帧。
* DISPOSE_ON_CLOSE(在WindowConstants中定义):自动隐藏和 在调用任何已注册的 WindowListener 后处置框架 对象。
* EXIT_ON_CLOSE(在 JFrame 中定义):退出 应用程序使用系统退出方法。仅在 应用程序。

默认情况下,该值设置为 HIDE_ON_CLOSE。 更改此属性的值会导致触发属性 更改事件,属性名称为“defaultCloseOperation”。

您可能还会发现 How to Make Frames (Main Windows) 有一些用处...

您还应该确保您的 UI 是在事件调度线程的上下文中创建的,请查看 Initial Threads 了解更多详细信息

更新示例

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);
    }
}

对我来说编译和运行都很好......

【讨论】:

  • 我会检查这些来源,但我最初使用 EXIT_ON_CLOSE 进行了尝试。它仍然无法编译,所以在阅读了这里的一些其他问题后,我想我会尝试 DISPOSE_ON_EXIT。
  • @twjohns29 真的,编译和运行对我来说都很好......特别是考虑到我从 Java 1.3 开始就一直在使用它......
  • 这很令人沮丧。我在 NetBeans IDE 8.0 上使用。我不确定这是否与它有关,但它在文本编辑器中给出一条消息,它找不到变量 CLOSE_ON_EXIT。
  • 我认为 DISPOSE_ON_CLOSE 是最好的方式。当用户关闭(最后一个)窗口时,VM 将结束。有关启动 3 帧的演示,请参阅 this answer。 VM 将在最后一帧关闭后退出。
  • @AndrewThompson 不同意,但是(禁止)您打开了两个窗口,例如,您可能希望“主”窗口始终退出程序。但我同意,这是捕获叛徒代码的好方法;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多