Hai ragione. Swing è la strada da percorrere, ma collegare tutti i pezzi può essere un po 'difficile se stai imparando Clojure e Swing. Ci sono alcuni brevi esempi che mostrano come creare semplici GUI Swing in Clojure. Ecco un altro breve esempio che combina una semplice interfaccia grafica con un oggetto Timer
.
(ns net.dneclark.JFrameAndTimerDemo
(:import (javax.swing JLabel JButton JPanel JFrame Timer))
(:gen-class))
(defn timer-action [label counter]
(proxy [java.awt.event.ActionListener] []
(actionPerformed
[e]
(.setText label (str "Counter: " (swap! counter inc))))))
(defn timer-fn []
(let [counter (atom 0)
label (JLabel. "Counter: 0")
timer (Timer. 1000 (timer-action label counter))
panel (doto (JPanel.)
(.add label))]
(.start timer)
(doto (JFrame. "Timer App")
(.setContentPane panel)
(.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
(.setLocation 300 300)
(.setSize 200 200)
(.setVisible true))))
(defn -main []
(timer-fn))
Quando eseguito, questo creerà una piccola finestra con un'etichetta che viene aggiornata ogni secondo. Dalla tua descrizione, cambieresti la frequenza del timer da 1.000 a 300.000 ms per attivare un'azione ogni 5 minuti. Per fare qualcosa di diverso dall'aggiornamento di un'etichetta, si cambierebbe il contenuto della funzione timer-action
.
I think questo thread è sicuro, ma non è stato verificato. Ci sono precauzioni e tutorial sulla sicurezza dei thread durante l'aggiornamento anche dei componenti Swing. Probabilmente vorrai controllare anche quelli.
Spero che questo sia abbastanza informativo per darti alcuni indizi su dove cercare ulteriori informazioni.
EDIT: volevo indicare una cosa più interessante qui.Si noti che la funzione 'timer-action' sta cambiando il valore di uno dei suoi argomenti. L'argomento 'contatore' è un atomo definito in 'timer-fn', ma il listener di azioni è in grado di cambiarlo. Questo è qualcosa che di solito non puoi fare in Java. Forse qualcuno più intelligente di me può commentare se questo costituisce una "chiusura". Nella mia precedente esperienza con linguaggi come Pascal, direi che l'argomento che passa è "call-by-reference" in opposizione al rigoroso argomento "call-by-value" di Java che passa. È qualcosa di diverso?
EDIT 2: Dopo aver verificato i miei fatti con un'altra domanda, questo è, in effetti, un esempio di chiusura in Clojure.
+1 per suggerire alternative. – trashgod
Buon inizio, ma hai completamente perso l'altalena (https://github.com/daveray/seesaw), che sembra rendere lo sviluppo dell'app meno doloroso in Clojure. – deterb