I'd like to create a simple Swing app. I've got very, very, very little experience with Swing, however. I want to create a one window app that refreshes every 5 minutes with the contents of a screen-scraping that I do. I'm using Clojure to write the code. I assume Swing is the way to go with this, but if there are other, better options I'd love to hear more about those as well.
What code would I need to do this with Swing? (what classes should I use, etc)
Thanks, Alex
In a Swing context, javax.swing.Timer
has some advantages; there's an example here. Depending on what you want to display, JEditorPane
may be appropriate.
Well, for the every five minutes bit, java.util.TimerTask should be of help. For general Swing information, this link to the Java Tutorials ought to help.
To have a Window, specifically, JFrame is probably your best bet.
To display single or multiline text, you ought to look into JLabel or JTextArea, respectively.
To display images, ImageIcon ought to do the trick.
For other needs, the Java Tutorial ought to be a big help.
As trashgod suggested, javax.swing.Timer has some advantages when it comes to GUIs over java.util.TimerTask. This article on using timers in Swing applications should help you decide which to use.
You're right. Swing is the way to go, but connecting all the pieces can be a bit tough if you're learning Clojure and Swing. There are a few short examples floating around showing how to create simple Swing GUIs in Clojure. Here's another short example that combines a simple GUI with a Timer
object.
(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))
When run, this will create a small window with a label that is updated every second. From your description, you would change the frequency of the timer from 1,000ms to 300,000ms to trigger an action every 5 minutes. To do something other than updating a label, you would change the contents of the timer-action
function.
I think this is thread safe, but haven't checked for sure. There are cautions and tutorials about thread safety when updating Swing components too. You'll probably want to check those too.
I hope this is informative enough to give yo a few clues as to where to look for further information.
EDIT: I wanted to point out one more interesting thing here. Note that the 'timer-action' function is changing the value of one of its arguments. The 'counter' argument is an atom defined in 'timer-fn', yet the action listener is able to change it. This is something you cannot usually do in Java. Maybe someone smarter than me can comment on whether this constitutes a "closure". In my previous experience with languages like Pascal, I would say the argument passing is "call-by-reference" as opposed to Java's strict "call-by-value" argument passing. Is this something different?
EDIT 2: After checking my facts with another question, this is, in fact, an example of a closure in Clojure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With