Zamykanie okna processinga z potwierdzeniem – SOLVED!

Niby prosta sprawa – okienko „zapisz rysunek” przy wychodzeniu z programu processinga. Nie chcemy utracić tworzonej grafiki (problem powstał podczas tworzenia obrazów w GRAPH CREATORZE – softwarze do obsługi Wielozadaniowej maszyny 2D/3D do zadań precyzyjnych), więc musi sie pojawić dialog o zapisie/odrzeceniu tworzonej pracy. Nie wystarczyło nadpisać funkcji exit() w processingu…

Okienka w Processingu oparte są (chyba) na tzw. JFrame’ach. Aby nimi sterować musimy się dostać do obiektu odpowiedzialnego za konkretne okno w aplikacji. Na początku trzeba utworzyć uchwyt do JFrame’a:

  import javax.swing.JFrame;
  import processing.awt.PSurfaceAWT;
  ...
  PSurfaceAWT surf = (PSurfaceAWT) getSurface();
  PSurfaceAWT.SmoothCanvas canvas = (PSurfaceAWT.SmoothCanvas) surf.getNative();
  JFrame jframe = (JFrame) canvas.getFrame(); //uchwyt
  ...

Otrzymany w ten sposób uchwyt można wykorzystać do modyfikacji działania okienka, np. ustawienie czynności przy zamykaniu okna:

jframe.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

Po dodaniu tych linijek kodu można zauważyć, że nic się nie zmieniło. Processing również rejestruje czy użytkownik próbuje zamknąć okno i wywołuje specjalną metodę to zamykania programu: exit(). 

Teraz wystarczy tą metodę nadpisać własnym kodem aby otrzymać dialog z potwierdzeniem wyłączenia programu:

void exit(){  // nadpisanie metody exit()
    int id = showConfirmDialog(
    frame,
    "Are you sure?", // tekst okienka
    "Exiting", // tytuł okna
    YES_NO_OPTION); // opcja przycisków
    if(id == 0){ //id 0 dla przycisku “Yes”
      super.exit();
    }
}

Okienko zwróci 0 dla przycisku “Yes”, 1 dla przysku “No” oraz -1 jeżeli zamkniemy okienko dialogowe wciskając “X”. Następnie można sprawdzić wartość zmiennej “id” i wywołać nienadpisaną wersję metody exit() przy użyciu super.exit() gdy “id” wynosi 1. Wówczas Processing zajmie się resztą i zamknie aplikację.

Do działania dialogów trzeba jeszcze dodać:

import static javax.swing.JOptionPane.*; (tutaj import jako klasa statyczna?)

Całość wygląda więc tak

import javax.swing.JFrame;
import processing.awt.PSurfaceAWT;
import static javax.swing.JOptionPane.*;

void setup(){
  size(900,600);
  PSurfaceAWT surf = (PSurfaceAWT) getSurface();
  PSurfaceAWT.SmoothCanvas canvas = (PSurfaceAWT.SmoothCanvas) surf.getNative();
  JFrame jframe = (JFrame) canvas.getFrame(); //uchwyt
  jframe.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
}
void draw(){
  rect(100,100, 200, 200);
}
void exit(){
  int id = showConfirmDialog(
    frame,
    "Are you sure?", // message
    "Exiting", // tytuł okna
    YES_NO_OPTION);
    println(id);
    if(id == 0){
      super.exit();
    }
}

I po problemie! Zachęcam do kopiowania tego rozwiząnia — (c) Bartosz Butler, 2019

Posted in FiBot and tagged , , , , .