Как переопределить событие windowsClosing в JFrame - PullRequest
2 голосов
/ 15 марта 2012

Я разрабатываю JFrame, в котором есть кнопка для отображения другого JFrame. На втором JFrame я хочу переопределить событие WindowsClosing, чтобы скрыть этот кадр, но не закрыть все приложение. Итак, я делаю так:

На втором JFrame

addWindowListener(new java.awt.event.WindowAdapter() {
    public void windowClosing(java.awt.event.WindowEvent evt) {
         formWindowClosing(evt);
    }
});

private void formWindowClosing(java.awt.event.WindowEvent evt) {
    this.dispose();
}

, но приложение все еще закрывается, когда я нажимаю кнопку x на окнах. Зачем? ты можешь мне помочь?

Я не могу использовать

setDefaultCloseOperation(DISPOSE_ON_CLOSE);

потому что мне нужно снова показать, что JFrame с некоторой информацией добавлен в него во время операций с первого JFrame. Поэтому я инициирую второй JFrame с атрибутом visible false. если я использую утилизацию, я теряю информацию, добавленную во второй момент другим JFrame. поэтому я использую

private void formWindowClosing(java.awt.event.WindowEvent evt) {
    this.setVisible(false);
}

но оно по-прежнему прекращает работу всего моего приложения.

Ответы [ 4 ]

4 голосов
/ 15 марта 2012

не создавайте новый JFrame, для нового контейнера используйте JDialog, если вы хотите скрыть JFrame, тогда лучше будет правильно переопределить, например, DefaultCloseOperations(JFrame.HIDE_ON_CLOSE), метод JFrame.EXIT_ON_CLOSE проверка текущего экземпляра JVM simlair как для System.exit(int)

EDIT

but it still continue to terminate my entire app. 

1) тогда должна быть другая проблема, ваш код может вызвать другой JFrame или formWindowClosing <> WindowClosing, используйте реализованный метод из API

public void windowClosing(WindowEvent e) {

2) Я бы предпочел DefaultCloseOperations(JFrame.HIDE_ON_CLOSE),

3) используйте JDialog вместо JFrame

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class ClosingFrame extends JFrame {

    private JMenuBar MenuBar = new JMenuBar();
    private static JFrame frame = new JFrame();
    private static JFrame frame1 = new JFrame("DefaultCloseOperation(JFrame.HIDE_ON_CLOSE)");
    private static final long serialVersionUID = 1L;
    private JMenu File = new JMenu("File");
    private JMenuItem Exit = new JMenuItem("Exit");

    public ClosingFrame() {
        File.add(Exit);
        MenuBar.add(File);
        Exit.addActionListener(new ExitListener());
        WindowListener exitListener = new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                frame.setVisible(false);
                /*int confirm = JOptionPane.showOptionDialog(frame,
                "Are You Sure to Close this Application?",
                "Exit Confirmation", JOptionPane.YES_NO_OPTION,
                JOptionPane.QUESTION_MESSAGE, null, null, null);
                if (confirm == JOptionPane.YES_OPTION) {
                System.exit(1);
                }*/
            }
        };
        JButton btn = new JButton("Show second JFrame");
        btn.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                frame1.setVisible(true);
            }
        });
        frame.add(btn, BorderLayout.SOUTH);
        frame.addWindowListener(exitListener);
        frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
        frame.setJMenuBar(MenuBar);
        frame.setPreferredSize(new Dimension(400, 300));
        frame.setLocation(100, 100);
        frame.pack();
        frame.setVisible(true);
    }

    private class ExitListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            int confirm = JOptionPane.showOptionDialog(frame,
                    "Are You Sure to Close this Application?",
                    "Exit Confirmation", JOptionPane.YES_NO_OPTION,
                    JOptionPane.QUESTION_MESSAGE, null, null, null);
            if (confirm == JOptionPane.YES_OPTION) {
                System.exit(1);
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                ClosingFrame cf = new ClosingFrame();
                JButton btn = new JButton("Show first JFrame");
                btn.addActionListener(new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        frame.setVisible(true);
                    }
                });
                frame1.add(btn, BorderLayout.SOUTH);
                frame1.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
                frame1.setPreferredSize(new Dimension(400, 300));
                frame1.setLocation(100, 400);
                frame1.pack();
                frame1.setVisible(true);
            }
        });
    }
}
2 голосов
/ 15 марта 2012

Добавление нового кода без части WindowListener, как объясняет @JBNizet, очень правильная вещь.Поведение по умолчанию просто скрывает окно, ничего не теряется, вам просто нужно вернуть его обратно, каждое значение внутри него останется как есть, ниже приведен пример программы для получения дополнительной помощи:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class TwoFrames
{
    private SecondFrame secondFrame;
    private int count = 0;

    private void createAndDisplayGUI()
    {
        JFrame frame = new JFrame("JFRAME 1");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationByPlatform(true);

        secondFrame = new SecondFrame();
        secondFrame.createAndDisplayGUI();
        secondFrame.tfield.setText("I will be same everytime.");

        JPanel contentPane = new JPanel();  
        JButton showButton = new JButton("SHOW JFRAME 2");
        showButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                secondFrame.tfield.setText(secondFrame.tfield.getText() + count);
                count++;
                if (!(secondFrame.isShowing()))
                    secondFrame.setVisible(true);
            }
        });

        frame.add(contentPane, BorderLayout.CENTER);
        frame.add(showButton, BorderLayout.PAGE_END);
        frame.setSize(200, 200);
        frame.setVisible(true);
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new TwoFrames().createAndDisplayGUI();
            }
        });
    }
}

class SecondFrame extends JFrame
{
    private WindowAdapter windowAdapter;
    public JTextField tfield;

    public void createAndDisplayGUI()
    {
        setLocationByPlatform(true);

        JPanel contentPane = new JPanel();

         tfield = new JTextField(10);

        addWindowListener(windowAdapter);
        contentPane.add(tfield);

        getContentPane().add(contentPane);
        setSize(300, 300);      
    }
}

Это то, что вы хотите, попробуйте этот код:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class TwoFrames
{
    private SecondFrame secondFrame;

    private void createAndDisplayGUI()
    {
        JFrame frame = new JFrame("JFRAME 1");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationByPlatform(true);

        secondFrame = new SecondFrame();
        secondFrame.createAndDisplayGUI();
        secondFrame.tfield.setText("I will be same everytime.");

        JPanel contentPane = new JPanel();  
        JButton showButton = new JButton("SHOW JFRAME 2");
        showButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                if (!(secondFrame.isShowing()))
                    secondFrame.setVisible(true);
            }
        });

        frame.add(contentPane, BorderLayout.CENTER);
        frame.add(showButton, BorderLayout.PAGE_END);
        frame.setSize(200, 200);
        frame.setVisible(true);
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new TwoFrames().createAndDisplayGUI();
            }
        });
    }
}

class SecondFrame extends JFrame
{
    private WindowAdapter windowAdapter;
    public JTextField tfield;

    public void createAndDisplayGUI()
    {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationByPlatform(true);

        JPanel contentPane = new JPanel();

         tfield = new JTextField(10);

        windowAdapter = new WindowAdapter()
        {
            public void windowClosing(WindowEvent we)
            {
                setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
            }
        };

        addWindowListener(windowAdapter);
        contentPane.add(tfield);

        getContentPane().add(contentPane);
        setSize(300, 300);      
    }
}
2 голосов
/ 15 марта 2012

Вы можете полностью избежать прослушивателя и использовать

setDefaultCloseOperation(DISPOSE_ON_CLOSE);

Обратите внимание, что значением по умолчанию является HIDE_ON_CLOSE, поэтому требуемое поведение должно быть поведением по умолчанию.Возможно, вы зарегистрировали другого слушателя, который выходит из приложения.

См. http://docs.oracle.com/javase/6/docs/api/javax/swing/JFrame.html#setDefaultCloseOperation%28int%29

1 голос
/ 15 марта 2012

Трудно точно определить, почему вы испытываете указанное поведение, не видя чуть больше кода настройки, однако это может быть связано с установкой defaultCloseOperation на EXIT_ON_CLOSE.

Вот ссылка на демонстрацию, отображающую свойства, которые вы ищете, хотя структура немного другая. Посмотрите: http://docs.oracle.com/javase/tutorial/uiswing/examples/components/FrameworkProject/src/components/Framework.java

...