프로그래밍 방식으로 JFrame을 닫는 방법


251

JFrame사용자가 X닫기 버튼을 눌렀거나 Alt+ F4(Windows)를 눌렀을 때 와 마찬가지로 a 를 닫는 올바른 방법은 무엇입니까 ?

기본 닫기 작업을 원하는 방식으로 설정했습니다.

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

위에서 언급 한 컨트롤로 원하는 것을 정확하게 수행합니다. 이 질문은 그것에 관한 것이 아닙니다.

내가 정말로하고 싶은 것은 GUI가 X닫기 버튼을 누르는 것과 같은 방식으로 작동하게하는 것입니다.

WindowAdaptor를 통해 어댑터의 인스턴스 를 확장 한 다음 리스너로 추가 한다고 가정 addWindowListener()합니다. 나는 통해 호출 같은 순서를보고 싶다 windowDeactivated(), windowClosing()그리고 windowClosed()발생하는 것처럼 X닫기 버튼. 말하기 위해 창을 찢어 버리는 것만 큼 창을 찢지 마십시오.


10
처분을 사용하는 데 무엇이 문제입니까? 그게 항상 내가 한 방식입니다.

1
예, jFrame.dispose ()는 창을 닫고 모든 것을 정리해야합니까?
Tom Neyland

4
dispose는 [x]를 클릭하여 창을 닫는 것과 1 : 1이 아니므로?
greenoldman

2
네, 좋은 질문입니다. 사용자가 장식되지 않은 JFrame 재정의를 명시 적으로 제공 하여 사용자가 OS 별 데코 레이팅 된 JFrame 창의 OS 제공 [x] 버튼을 클릭 한 것처럼 정확하게 작동하도록 명시 적으로 제공하고자합니다 .
peterk

이건 어떻습니까 .dispatchEvent (wev); Toolkit.getDefaultToolkit 대신 ... 전자가 받아 들인 대답이 제안합니다.
Jason

답변:


320

X닫기 버튼을 클릭 한 것처럼 GUI가 동작하도록하려면 창 닫기 이벤트를로 전달해야합니다 Window. ExitAction에서 응용 프로그램을 닫기는 사용자가 메뉴 항목이나 구성 요소 사용에이 기능을 추가 할 수 Action의 쉽게.

frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));

this.jframe.addWindowListener (new WindowAdapter () {@Override public void windowClosing (WindowEvent e) {e.getWindow (). dispose ();}});를 추가해야합니까? 전화하기 전에? 아니면 창문을 닫을까요?
mmm

1
"프로그래밍 방식으로 JFrame을 닫는 방법"-JFrame.EXIT_ON_CLOSE가 설정되어 있지 않으면 닫히지 않습니다. 어쨌든 jframe.setDefaultCloseOperation (WindowConstants.DO_NOTHING_ON_CLOSE); 이후 답변에 추가해야 할 수도 있다고 지적했습니다. DO_NOTHING_ON_CLOSE가 설정되어 있어도 사용자가 일반적으로 X에서 창을 닫을 수 있음에도 불구하고 실제로이 이벤트를 트리거하여 닫지 않습니다. 그러나이 이벤트를 발생시키는 것은 아닙니다. 차이점을 보시겠습니까?
mmm

3
@ momomo, 아무것도 지적 할 필요가 없었습니다. 이 답변은 OP가 요청한대로 정확하게 수행됩니다. "X"닫기 버튼이하는 모든 작업을 수행합니다. 질문의 제목은 질문이 아닙니다. OP는 구체적으로 기본 닫기 작업이 "종료"로 설정되어 있으므로 OP가 요청하지 않았기 때문에 "아무것도하지 않음"이 수행하는 것은 관련이 없습니다. 이 답변을 읽는 다른 사람들을 혼동하지 않도록 모든 의견을 삭제하십시오. 답변은 질문의 제목에 대한 해석이 아니라 OP의 질문에 직접 답변하기 위해 제공 되었기 때문입니다.
camickr

131
setVisible(false); //you can't see me!
dispose(); //Destroy the JFrame object

너무 까다 롭지 않습니다.


38
그러나 이것은 이벤트 리스너를 호출하지 않습니다.
Bombe

6
또한이 버튼이 닫기 버튼이면 백그라운드에서 프로세스가 계속 실행됩니다.
Austin A

1
기본 닫기 작업이 EXIT_ON_CLOSE에 있거나 버튼 리스너가 필요한 리소스 닫기를 수행하는 경우 아닙니다.
멜린다 녹색

리스너를 호출하지 않습니다.
Stefan Reich

26

Alt-F4 또는 X가 "다른 Windows 또는 스레드가 실행중인 것을 고려하지 않고 즉시 응용 프로그램 종료"를 의미 하는 경우 매우 갑작스럽고 무차별적이고 문제가있는 방식으로 원하는 System.exit(...)작업을 정확하게 수행 합니다 .

Alt-F4 또는 X가 창을 숨기는 것을 의미하는 경우 창 frame.setVisible(false)을 "닫는"방법입니다. 이 창은 계속 리소스 / 메모리를 사용하지만 매우 빠르게 다시 표시 될 수 있습니다.

Alt-F4 또는 X에 의해 창을 숨기고 사용중인 자원을 폐기한다는 것은 창 frame.dispose()을 "닫는"방법입니다. 프레임이 마지막으로 보이는 창이고 실행중인 다른 비 데몬 스레드가없는 경우 프로그램이 종료됩니다. 창을 다시 표시하면 모든 기본 자원 (그래픽 버퍼, 창 핸들 등)을 다시 초기화해야합니다.

dispose()당신이 정말로 원하는 행동에 가장 가깝습니다. 앱에 여러 창이 열려있는 경우 Alt-F4 또는 X에서 앱을 종료하거나 활성 창을 닫으시겠습니까?

Window ListenersJava Swing Tutorial 이 내용을 명확히하는 데 도움이 될 수 있습니다.


15

사용자가 창을 닫을 수 없도록하기 위해이를 수행 한 경우 :

frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

그런 다음 pullThePlug()방법을 변경해야 합니다.

public void pullThePlug() {
    // this will make sure WindowListener.windowClosing() et al. will be called.
    WindowEvent wev = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
    Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);

    // this will hide and dispose the frame, so that the application quits by
    // itself if there is nothing else around. 
    setVisible(false);
    dispose();
    // if you have other similar frames around, you should dispose them, too.

    // finally, call this to really exit. 
    // i/o libraries such as WiiRemoteJ need this. 
    // also, this is what swing does for JFrame.EXIT_ON_CLOSE
    System.exit(0); 
}

나는 이것이 WindowListenerand와 잘 어울리는 유일한 방법이라는 것을 알았습니다 JFrame.DO_NOTHING_ON_CLOSE.


11

옵션은 다음과 같습니다.

System.exit(0); // stop program
frame.dispose(); // close window
frame.setVisible(false); // hide window

8

Java 실행 프로세스를 종료하는 것은 매우 쉽습니다. 기본적으로 두 가지 간단한 작업 만 수행하면됩니다.

  1. System.exit(...)응용 프로그램 종료점에서 Java 메소드 를 호출하십시오 . 예를 들어, 애플리케이션이 프레임 기반 인 경우 리스너를 추가 하고 메소드 내부에서 WindowAdapter호출 할 수 있습니다 .System.exit(...)windowClosing(WindowEvent e)

참고 : System.exit(...)그렇지 않으면 호출해야합니다 . 프로그램에 오류가 있습니다.

  1. exit 메소드를 항상 호출 할 수 있도록 예기치 않은 Java 예외를 피하십시오. System.exit(...)올바른 지점에 추가 하더라도 예기치 않은 Java 예외로 인해 메소드가 호출되지 않을 수 있으므로 항상 메소드를 호출 할 수있는 것은 아닙니다.

이것은 프로그래밍 기술과 밀접한 관련이 있습니다.

** 다음은 JFrameexit 메소드를 호출하는 방법을 보여주는 가장 간단한 샘플 ( 기반)입니다.

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

public class ExitApp extends JFrame
{
   public ExitApp()
   {
      addWindowListener(new WindowAdapter()
      {
         public void windowClosing(WindowEvent e)
         {
           dispose();
           System.exit(0); //calling the method is a must
         }
      });
   }

   public static void main(String[] args)
   {
      ExitApp app=new ExitApp();
      app.setBounds(133,100,532,400);
      app.setVisible(true);
   }
}

7

JFrame을 닫을뿐만 아니라 WindowListener 이벤트를 트리거하려면 다음을 시도하십시오.

myFrame.dispatchEvent(new WindowEvent(myFrame, WindowEvent.WINDOW_CLOSING));

4

프로그래밍 방식으로 스윙 프레임을 닫는 가장 좋은 방법은 "X"버튼을 눌렀을 때와 같이 동작하는 것입니다. 이를 위해서는 필요에 맞는 WindowAdapter를 구현하고 아무 것도하지 않도록 프레임의 기본 닫기 작업을 설정해야합니다 (DO_NOTHING_ON_CLOSE).

다음과 같이 프레임을 초기화하십시오.

private WindowAdapter windowAdapter = null;

private void initFrame() {

    this.windowAdapter = new WindowAdapter() {
        // WINDOW_CLOSING event handler
        @Override
        public void windowClosing(WindowEvent e) {
            super.windowClosing(e);
            // You can still stop closing if you want to
            int res = JOptionPane.showConfirmDialog(ClosableFrame.this, "Are you sure you want to close?", "Close?", JOptionPane.YES_NO_OPTION);
            if ( res == 0 ) {
                // dispose method issues the WINDOW_CLOSED event
                ClosableFrame.this.dispose();
            }
        }

        // WINDOW_CLOSED event handler
        @Override
        public void windowClosed(WindowEvent e) {
            super.windowClosed(e);
            // Close application if you want to with System.exit(0)
            // but don't forget to dispose of all resources 
            // like child frames, threads, ...
            // System.exit(0);
        }
    };

    // when you press "X" the WINDOW_CLOSING event is called but that is it
    // nothing else happens
    this.setDefaultCloseOperation(ClosableFrame.DO_NOTHING_ON_CLOSE);
    // don't forget this
    this.addWindowListener(this.windowAdapter);
}

다음과 같이 WINDOW_CLOSING 이벤트를 보내 프로그래밍 방식으로 프레임을 닫을 수 있습니다.

WindowEvent closingEvent = new WindowEvent(targetFrame, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(closingEvent);

"X"버튼을 누른 것처럼 프레임이 닫힙니다.


4

JFrame을 닫을 때 응용 프로그램을 실제로 종료하지 않으려면

사용하다 : setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

대신에 : setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

솔루션의 모습에 대한 개요는 다음과 같습니다.

 myFrame.dispatchEvent(new WindowEvent(myFrame, WindowEvent.WINDOW_CLOSING));

4

이 답변은 Alex가 제공했으며 추천하고 싶습니다. 그것은 나를 위해 일했고 간단하고 간단합니다.

setVisible(false); //you can't see me!
dispose(); //Destroy the JFrame object

1
답변을 반복하고 (+90 표로) 귀하에게 도움이되었다고 말하는 것의 가치는 무엇입니까? 아마도 당신은 당신이 반복 한 대답에 대한 의견에서 그것이 당신을 위해 일했는지 확인해야합니까?
TT.

정말 유감입니다 만 때때로 어떤 사람들은 추천 된 것을 사용하여 더 자신감을 느낄 것입니다
Humphrey

나는 당신이 말하는 것을 이해하지만, 효과가있는 답변을 사용한 모든 사람이 다른 답변이 나를 위해 일했다는 답변을 추가한다고 가정합니다. 어떻게 보일까요? 수백 개의 답변이 다른 답변의 반복입니다. IMO 당신에게 도움이되는 답변을 찬성하는 것이 좋습니다. 어떤 가치를 더한다면 답변에 의견을 남기십시오.
TT.

고마워요 당신의 요점과 다음에 내가 코멘트를 남기기 위해 할 것입니다. 그러나 나는 공감했다.
험프리

2
아니요, 공감 해야합니다 . 의견을 남기지 말고 다른 답변을 올리지 마십시오.
user202729

3

이 예제는 확인 된 창 닫기 조작을 실현하는 방법을 보여줍니다.

창에는 기본 닫기 작업을 EXIT_ON_CLOSE또는 DO_NOTHING_ON_CLOSE의 답변에 따라 달라지는 창 어댑터가 OptionDialog있습니다.

창 닫기 이벤트를 발생시키는 방법 closeWindowConfirmedCloseWindow어디서나 메뉴 항목의 동작으로 사용할 수 있습니다.

public class WindowConfirmedCloseAdapter extends WindowAdapter {

    public void windowClosing(WindowEvent e) {

        Object options[] = {"Yes", "No"};

        int close = JOptionPane.showOptionDialog(e.getComponent(),
                "Really want to close this application?\n", "Attention",
                JOptionPane.YES_NO_OPTION,
                JOptionPane.INFORMATION_MESSAGE,
                null,
                options,
                null);

        if(close == JOptionPane.YES_OPTION) {
           ((JFrame)e.getSource()).setDefaultCloseOperation(
                   JFrame.EXIT_ON_CLOSE);
        } else {
           ((JFrame)e.getSource()).setDefaultCloseOperation(
                   JFrame.DO_NOTHING_ON_CLOSE);
        }
    }
}

public class ConfirmedCloseWindow extends JFrame {

    public ConfirmedCloseWindow() {

        addWindowListener(new WindowConfirmedCloseAdapter());
    }

    private void closeWindow() {
        processWindowEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
    }
}

3

여기에 이미 제공된 답변을 바탕으로 이것이 내가 구현 한 방식입니다.

JFrame frame= new JFrame()
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// frame stuffs here ...

frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));

JFrame은 이벤트를 닫고 닫으면 종료합니다.


2

모든 타이밍이 올바르게 발생하도록 AWT 메시지 큐에 호출을 삽입해야합니다. 그렇지 않으면 특히 다중 스레드 프로그램에서 올바른 이벤트 순서를 전달하지 않습니다. 이 작업이 완료되면 사용자가 OS 제공 데코 레이팅 된 JFrame에 대해 [x] 버튼을 클릭 한 경우와 동일한 결과 이벤트 순서를 처리 할 수 ​​있습니다.

public void closeWindow()
{
    if(awtWindow_ != null) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                awtWindow_.dispatchEvent(new WindowEvent(awtWindow_, WindowEvent.WINDOW_CLOSING));
            }
        });
    }
}

2

나는 이것을 시도했다, formWindowClosing () 이벤트에 대한 자신의 코드를 작성하십시오 .

 private void formWindowClosing(java.awt.event.WindowEvent evt) {                                   
    int selectedOption = JOptionPane.showConfirmDialog(null,
            "Do you want to exit?",
            "FrameToClose",
            JOptionPane.YES_NO_OPTION);
    if (selectedOption == JOptionPane.YES_OPTION) {
        setVisible(false);
        dispose();
    } else {
        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
    }
}    

프레임 또는 응용 프로그램을 종료할지 여부를 묻습니다.


1

질문 본문에있는 내용을 CW 답변으로 게시

주로 camickr의 링크를 통해 얻은 결과를 공유하고 싶었습니다. 기본적으로 WindowEvent.WINDOW_CLOSING응용 프로그램의 이벤트 대기열 에을 던져야합니다 . 솔루션의 모습에 대한 개요는 다음과 같습니다.

// closing down the window makes sense as a method, so here are
// the salient parts of what happens with the JFrame extending class ..

    public class FooWindow extends JFrame {
        public FooWindow() {
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setBounds(5, 5, 400, 300);  // yeah yeah, this is an example ;P
            setVisible(true);
        }
        public void pullThePlug() {
                WindowEvent wev = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
                Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
        }
    }

// Here's how that would be employed from elsewhere -

    // someplace the window gets created ..
    FooWindow fooey = new FooWindow();
    ...
    // and someplace else, you can close it thusly
    fooey.pullThePlug();

1

JFrame을 닫을 때 응용 프로그램을 종료하지 않으려면 setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE)을 사용하십시오.

대신 : setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

설명서에서 :

DO_NOTHING_ON_CLOSE (defined in WindowConstants): 아무 것도하지 마십시오. 프로그램이 등록 된 WindowListener 객체의 windowClosing 메서드에서 작업을 처리하도록 요구합니다.

HIDE_ON_CLOSE (defined in WindowConstants): 등록 된 WindowListener 객체를 호출 한 후 프레임을 자동으로 숨 깁니다.

DISPOSE_ON_CLOSE (defined in WindowConstants): 등록 된 WindowListener 객체를 호출 한 후 프레임을 자동으로 숨기고 처리합니다.

EXIT_ON_CLOSE (defined in JFrame): 시스템 종료 방법을 사용하여 응용 프로그램을 종료하십시오. 어플리케이션에서만 사용하십시오.

여전히 유용 할 수 있습니다 : setVisible(false)동일한 프레임을 다시 표시하려면 JFrame에서 사용할 수 있습니다 . 그렇지 않으면 dispose()모든 기본 화면 리소스를 제거하기 위해 호출 합니다.

피터 랭에서 복사

https://stackoverflow.com/a/1944474/3782247


0
 setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

이것은setVisible(false) .setVisible(false); .setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
Abhijeet
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.