processing
processing3

Processing3で閉じるボタンを押した時に終了確認する方法

はじめに

Processingで閉じるボタン(×ボタン?)を押した時に終了確認をする方法です。

実行環境

Processing3.3

コード

on_close_sample.pde
// 最初に閉じるボタンを押した時のみJPanelの表示までしばらく時間がかかる

import processing.awt.PSurfaceAWT;
import processing.awt.PSurfaceAWT.SmoothCanvas;
import java.awt.Canvas;

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

JFrame jframe;
SmoothCanvas canvas;

void setup() {
  // このスケッチのSmoothCanvasを取得
  canvas = (SmoothCanvas) surface.getNative();

  // canvasのFrameをJFrameにキャストして取得
  jframe = (JFrame) canvas.getFrame();

  // jframeのwindowListenerをremove
  // forで全てremoveしていいのか少し不安
  for (WindowListener evt : jframe.getWindowListeners()) {
    jframe.removeWindowListener(evt);
  }

  jframe.addWindowListener(new WindowClosing());

  size(400, 400);
}

void draw() {
  background(255);
  ellipse(200, 200, frameCount, 100);
}

// xボタンを押した時に発火するイベント
class WindowClosing extends WindowAdapter {
  public void windowClosing(WindowEvent e) {
    int ans = JOptionPane.showConfirmDialog(
      jframe, 
      new JPanel(),
      "本当に終了しますか?",
      JOptionPane.YES_NO_OPTION,
      JOptionPane.INFORMATION_MESSAGE
      );
    println(ans);

    if (ans == JOptionPane.YES_OPTION) {
      println("プログラムによる終了処理の実行");
      exit();
    } else {
      // Yes以外を押した時は何もしない
      jframe.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
    }
  }
}

終わりに

これで実装できますが、最初に閉じるボタンを押した時だけ、表示が遅いのが少し気になります。

なにか改善方法があれば教えていただけるとうれしいです。

参考

Preventing a PApplet closing the calling Java program - Processing Forum
embedding PApplet in Java JFrame - Processing Forum
ウィンドウクローズ時の終了確認ダイアログボックス - Javaをはじめよう
メッセージタイプを指定して選択ダイアログを表示する - JavaDrive
processingで選択ダイアログを表示する - qiita