Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Beginner to Swing

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

like image 917
Alex Baranosky Avatar asked Jan 21 '11 04:01

Alex Baranosky


3 Answers

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.

like image 33
trashgod Avatar answered Sep 28 '22 08:09

trashgod


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.

like image 97
Zach L Avatar answered Sep 28 '22 08:09

Zach L


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.

like image 33
clartaq Avatar answered Sep 28 '22 09:09

clartaq