简体   繁体   English

关闭JFrame时执行操作

[英]Performing action when closing JFrame

In my program I have a main JFrame that holds a button. 在我的程序中,我有一个包含按钮的主JFrame。 When this button is clicked a new JFrame appears in which I can change some information. 单击此按钮时,会出现一个新的JFrame,我可以在其中更改某些信息。 Whenever I finish editing I press a save button on the new JFrame which saves the changes and disposes the JFrame. 每当我完成编辑,我按下新JFrame上的保存按钮,保存更改并处理JFrame。 Now when this is done, I'd like to perform an action in the main JFrame as well, but only if something changed. 现在,完成此操作后,我还想在主JFrame中执行操作,但前提是更改了一些内容。 If I open the new JFrame and just close it again without using the save button, I don't want to do anything in the main frame. 如果我打开新的JFrame并在不使用保存按钮的情况下再次关闭它,我不想在主框架中执行任何操作。 I've tried searching the web for a solution, but just don't seem to be anything useful out there.. 我已经尝试在网上搜索解决方案,但似乎没有任何有用的东西..

An example of the code I've got so far: Main Frame... 我到目前为止的代码示例:主框架......


public class MainFrame extends JFrame
 {
     public MainFrame()
     {
         super("Main Frame");
         JButton details = new JButton("Add Detail");
         add(details);
         details.addActionListener(new ActionListener(){
             public void actionPerformed(ActionEvent e)
             {
                 new DetailFrame().setVisible(true);
             }
         });
     }
 }

Detail Frame... 细节框架......


 public class DetailFrame extends JFrame
 {
     public DetailFrame()
     {
         super("Detail Frame");
         JButton save = new JButton("Save");
         add(save);
         save.addActionListener(new ActionListener(){
             public void actionPerformed(ActionEvent e)
             {
                 // Save whatever content
                 dispose();
             }
         });
     }
 }

So when I click the "Save" button on the Detail Frame, I want to do something in the Main Frame, whereas when the "x" is clicked on the Detail Frame, I don't want to do anything.. 因此,当我单击Detail Frame上的“Save”按钮时,我想在主框架中执行某些操作,而当在Detail Frame上单击“x”时,我不想做任何事情。

Hope someone is able to help me, and sorry for my english.. 希望有人能帮助我,对不起我的英语..

You can pass a MainFrame handle to the DetailFrame constructor. 您可以将MainFrame句柄传递给DetailFrame构造函数。 Then, on clicking the Save button, the DetailFrame would call a function in MainFrame and pass the changes to it. 然后,在单击“保存”按钮时,DetailFrame将调用MainFrame中的函数并将更改传递给它。

Another way is to create a public boolean variable in DetailFrame and set it to true when the Save button is clicked. 另一种方法是在DetailFrame中创建一个public boolean变量,并在单击“保存”按钮时将其设置为true This way MainFrame will know whether the DetailFrame was closed or Save'd. 这样MainFrame就会知道DetailFrame是关闭还是Save'd。

EDIT: Some more ideas: 编辑:一些更多的想法:

Use JDialog instead of JFrame . 使用JDialog而不是JFrame JDialog.setVisible is modal, ie it will block the calling function until the dialog is closed; JDialog.setVisible是模态的,即它将阻止调用函数,直到对话框关闭; this way you can process the results of the dialog in the same "Details" button listener. 这样,您可以在同一个“详细信息”按钮侦听器中处理对话框的结果。

To access the dialog after it is called, store the dialog in a separate variable. 要在调用对话框后访问该对话框,请将对话框存储在单独的变量中。 First construct the dialog, then show it, and then process the result by analyzing its variables. 首先构造对话框,然后显示它,然后通过分析其变量来处理结果。

Store the results of editing in other public variables of DetailFrame (or let's call it DetailDialog ). 将编辑结果存储在DetailFrame其他公共变量中(或者将其称为DetailDialog )。 This should happen only when the "Save" button is clicked. 只有在单击“保存”按钮时才会发生这种情况。 This may even allow to go without the boolean variable (depends on the types of values you are editing). 这甚至可以允许没有布尔变量(取决于您正在编辑的值的类型)。

DetailDialog dlg = new DetailDialog();
dlg.setVisible(true);
if(dlg.approvedResult != null) {
    // process the result...
}

EDIT: Sorry, JDialog is not modal by default. 编辑:对不起, JDialog默认情况下不是模态的。 Need to call a special super constructor to make it modal. 需要调用一个特殊的super构造函数来使其成为模态。

Also, here you will have to pass the reference to MainFrame to the dialog constructor, but you still can declare it as a simple JFrame and avoid unnecessary dependencies. 此外,在这里您必须将对MainFrame的引用传递给对话框构造函数,但您仍然可以将其声明为简单的JFrame并避免不必要的依赖项。

To get the reference to the enclosing MainFrame from within the anonymous ActionListener, use MainFrame.this . 要从匿名ActionListener中获取对封闭MainFrame的引用,请使用MainFrame.this

To be able to change the button text after it was created, you will have to store the button in a member variable. 为了能够在创建按钮文本后更改按钮文本,您必须将按钮存储在成员变量中。

Main Frame... 主框架......

public class MainFrame extends JFrame
{
    private JButton details = new JButton("Add Detail");

    public MainFrame()
    {
        super("Main Frame");
        getContentPane().add(details);
        details.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                DetailDialog dlg = new DetailDialog(MainFrame.this);
                dlg.setVisible(true);
                if(dlg.approved){
                    details.setText("Edit Detail");
                }
            }
        });
    }
}

Detail Dialog... (not Frame) 细节对话框...(不是框架)

public class DetailDialog extends JDialog
{
    public boolean approved = false;

    public DetailDialog(JFrame parent)
    {
        super(parent,"Detail Dialog",true);        // modal dialog parented to the calling frame
        JButton save = new JButton("Save");
        getContentPane().add(save);
        save.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                // Save whatever content
                approved = true;
                dispose();
            }
        });
    }
}

Create the detail frame in the main frame, and add a windowlistener to it, using the windowadapter class. 在主框架中创建细节框架,并使用windowadapter类向其添加windowlistener。 Implement the windowclosing event by checking for changes, handle those, and then dispose the detail frame. 通过检查更改,处理这些更改,然后处置详细信息框来实现windowclosing事件。 This is all done in the mainframe. 这一切都在大型机中完成。

The detail frame should have do nothing on close set to prevent the detail frame being disposed before you recorded the changes. 细节框架应该在关闭集上不执行任何操作,以防止在记录更改之前处理细节框架。

You may wish to implement checking for changes in the detailframe as a method returning a class holding the interesting data. 您可能希望实现检查详细信息框中的更改,作为返回保存有趣数据的类的方法。 That way your windowlistener can be small an to the point. 这样你的windowlistener可以很小到一点。

Forget the 2nd JFrame . 忘掉第二个JFrame use a modal dialog instead. 改为使用模态对话框。 It will block input until dismissed. 它会阻止输入直到被解雇。 Once dismissed, the only thing to do is decide whether to update the original data. 一旦被解雇,唯一要做的就是决定是否更新原始数据。 JOptionPane has some inbuilt functionality that makes that easy. JOptionPane具有一些内置功能,可以轻松实现。 If the user presses Cancel or the esc key, the showInputDialog() method will return null as the result. 如果用户按下Cancelesc键,则showInputDialog()方法将返回null作为结果。

import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;

class EditInfo {

    public static void main(String[] args) {

        Runnable r = new Runnable() {
            public void run() {
                final JFrame f = new JFrame("Uneditable");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                JPanel p = new JPanel(new BorderLayout(10,10));

                final JTextField tf = new JTextField("Hello World!", 20);
                tf.setEnabled(false);
                p.add(tf, BorderLayout.CENTER);

                JButton edit = new JButton("Edit");
                edit.addActionListener( new ActionListener(){
                    public void actionPerformed(ActionEvent ae) {
                        String result = JOptionPane.showInputDialog(
                            f,
                            "Edit text",
                            tf.getText());
                        if (result!=null) {
                            tf.setText(result);
                        }
                    }
                } );
                p.add(edit, BorderLayout.EAST);

                p.setBorder(new EmptyBorder(10,10,10,10));

                f.setContentPane(p);
                f.pack();
                f.setLocationByPlatform(true);
                f.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

If it is necessary to edit a number of fields all at once in the JOptionPane , use a JPanel to contain them all, and put them in a showMessageDialog() call. 如果需要在JOptionPane中一次编辑多个字段,请使用JPanel将它们全部包含showMessageDialog() ,并将它们放在showMessageDialog()调用中。 Check the integer based return result to determine if the user OK'd the changes. 检查基于整数的返回结果,以确定用户是否确定了更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM