TITLE:JOptionPaneを自動的に閉じる
#navi(../)
#tags(JOptionPane, Timer, HierarchyListener, JLabel)
RIGHT:Posted by &author(aterai); at 2013-09-02
* JOptionPaneを自動的に閉じる [#q5e9254b]
`JOptionPane`にカウントダウンと自動クローズを行うための`JLabel`を追加します。

#download
#ref(https://lh6.googleusercontent.com/-NvrpIdRXy8M/UiMOJmS8OMI/AAAAAAAABzg/6QK49B0s-NE/s800/AutomaticallyCloseDialog.png)

** サンプルコード [#cd625d9b]
#code(link){{
label.addHierarchyListener(new HierarchyListener() {
  private Timer timer = null;
  private AtomicInteger atomicDown = new AtomicInteger(SECONDS);
  @Override public void hierarchyChanged(HierarchyEvent e) {
    final JLabel l = (JLabel)e.getComponent();
    if((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED)!=0) {
      if(l.isShowing()) {
        textArea.append("isShowing=ture\n");
        atomicDown.set(SECONDS);
        l.setText(String.format("Closing in %d seconds", SECONDS));
        timer = new Timer(1000, new ActionListener() {
          //private int countdown = SECONDS;
          @Override public void actionPerformed(ActionEvent e) {
            //int i = --countdown;
            int i = atomicDown.decrementAndGet();
            l.setText(String.format("Closing in %d seconds", i));
            if(i<=0) {
              Window w = SwingUtilities.getWindowAncestor(l);
              if(w!=null && timer!=null && timer.isRunning()) {
                textArea.append("Timer: timer.stop()\n");
                timer.stop();
                textArea.append("window.dispose()\n");
                w.dispose();
              }
            }
          }
        });
        timer.start();
      }else{
        textArea.append("isShowing=false\n");
        if(timer!=null && timer.isRunning()) {
          textArea.append("timer.stop()\n");
          timer.stop();
          timer = null;
        }
      }
    }
  }
});
}}

** 解説 [#g03a2618]
- `java.awt.event.HierarchyListener`
-- `HierarchyListener`を使って、`JLabel`の表示状態の変化を監視
--- [[JOptionPaneのデフォルトフォーカス>Swing/OptionPaneDefaultFocus]]
- `javax.swing.Timer`
-- `JLabel`の表示状態の変化し、`JLabel#isShowing()`が`true`となって親の`JOptionPane`が表示されたら、`Timer#start()`でカウントダウンを開始
--- [[JComponentの表示状態>Swing/ShowingDisplayableVisible]]
-- 指定した時間が経過したら、`Window#dispose()`を使って、親の`JOptionPane`を自動的に閉じる
--- `Window#dispose()`を使うので、`JOptionPane.showConfirmDialog(...)`の戻り値は、`JOptionPane.CLOSED_OPTION`になる

** 参考リンク [#oc1924dd]
- [[JComponentの表示状態>Swing/ShowingDisplayableVisible]]
- [[JOptionPaneのデフォルトフォーカス>Swing/OptionPaneDefaultFocus]]
- [http://stackoverflow.com/questions/10021969/java-how-to-continuously-update-jlabel-which-uses-atomicinteger-to-countdown-af swing - Java: How to continuously update JLabel which uses atomicInteger to countdown after ActionListener - Stack Overflow]

** コメント [#de2bf5bd]
#comment