Stoppt die Vorratsdatenspeicherung! Jetzt klicken &handeln! Willst du auch an der Aktion teilnehmen? Hier findest du alle relevanten Infos
  und Materialien:

Skip to content


Clojure

Clojure logo

I’ve been trying out Clojure lately. Clojure is a new lisp dialect, that is hosted on the JVM and interoperates nicely with it. You can easily use Java methods, classes and libraries. I’ve been using it a little bit, watching some videos about it on blip.tv by it’s author, Rich Hickey, which really is a brilliant guy. You should check them out as well, they give you a pretty good introduction to the language.

Compared to Common Lisp, which I really like allot as well, Clojure does feel a little bit more modern. For example, being not limited to reader support for lists, but also having maps and vectors (like arrays) as first class citizens, is really nice. And then theres the huge emphasis on multithreading support in a really nice way without locks and condition variables but with a stm (software transactional memory). Clojure is a functional language and focuses on immutability of data structures compared to Common Lisp, which also allows a more imperative style, if you want to. In Clojure, you’re forced to a functional style, which might seem like a downside at first, but which makes it possible to have some pretty neat features concerning multithreaded programming support. Since all the datastructures are immutable, there’s no need do use locks when having multiple threads sharing them. I suggest checking out the videos and to give Clojure a try. It seems very promising and it’s having quite a publicity boost right now. Just google for it, take a look on some mailinglists or checkout reddit etc. You’ll find plenty comments, links and blogposts about it (like this one ;) ).

So since I thought it’s always nice to try to port an existing little application from a language I already know to a new one I want to learn, I tried to port a very small programm CallToPower, a collegue from university, wrote and posted on his website. I pretty much copied it straightly to Clojure, changing some parts.

Now I know this might not be the best way to write it in Clojure. But it was my real first (although very small) programm in Clojure and I wanted to make it as close to the original, as possible. Basically, what it does is display some values of some system properties you can choose by pressing the appropriate. Nothing fancy, but it shows some Clojure related stuff pretty well.

So here’s the code, use it as you like:

(ns sysinfo
  (:gen-class)
  (:import (java.awt BorderLayout
		     GridLayout)
	   (java.awt.event ActionEvent
			   ActionListener)
	   (javax.swing JFrame
			JPanel
			JLabel
			JButton)))
 
(def *x-coord* 30)
(def *y-coord* 30)
(def *width* 800)
(def *height* 230)
(def *prog-name* "SysInfo 1.0 [Clojure]")
(def *visible* true)
(def *resizable* true)
(def *frame* nil)
 
(def *label-property-mappings*
     { "OS Name" "os.name",
       "OS Architecture" "os.arch",
       "Java Classpath" "java.class.path",
       "Java Version" "java.version",
       "Current working directory" "user.dir",
       "Resize to default" "Resize to default",
       "Clear" " "})
 
(defn resize-frame
  [frame a b awidth bheight]
  (doto frame
    (.setBounds a b awidth bheight)))
 
 
(defn set-label-text [label text]
  (doto label
    (.setText text)))
 
(defn button-listener
  "Returns a ActionListener, which sets the text of the content label (label-content)
  to the appropriate system property (System.getProperty)."
  [property label frame]
  (proxy [ActionListener] []
    (actionPerformed [evt]
		     (let [system-property-value (. System getProperty property)]
		       (if (not (.equalsIgnoreCase property "Resize to default"))
			 (if (not (.equalsIgnoreCase property " "))
			   (set-label-text label (str (.getActionCommand evt) ": \n" system-property-value))
			   (set-label-text label property))
			 (resize-frame frame *x-coord* *y-coord* *width* *height*))))))
 
 
(defmacro doto-each
  "Macro, that works like doto-macro, only that it does it for each object in objects.
  varname is bound to each object in turn inside of the body (forms) and can be used to access the current
  object, if needed."
  [[varname [& objects]] & forms]
  `(do
     ~@(map (fn [f] `(let [~varname ~f]
		       (doto ~f
			 ~@forms)))
	    objects)))
 
(defmacro add-each
  "Macro, that calls .add on to-object with each object in objects."
  [to-object [& objects]]
  `(do
     ~@(map (fn [o] `(.add ~to-object ~o))
	    objects)))
 
(defn create-new-sysinfo-window
  "Creates the main form and returns it. Mainly GUI-related stuff (javax.swing)."
  []
  (let [frame (JFrame. "Adztec-Independent.de: SysInfo Clojure-style!")
	panel-header (JPanel.)
	panel-main (JPanel. (BorderLayout.))
	panel-left (JPanel. (GridLayout. 6 1))
	panel-south (JPanel. (GridLayout. 1 1))
	;; labels
	label-header (JLabel. "System Information")
	label-blank (JLabel. " ")
	label-content (JLabel. " ")
	label-adztec-indep (JLabel. "by www.adztec-independent.de")]
 
    (.setHorizontalAlignment label-blank (JLabel/CENTER))
    (.setHorizontalAlignment label-adztec-indep (JLabel/CENTER))
 
    ;; buttons
    (let [btn-java-cp (JButton. "Java Classpath")
	  btn-java-version (JButton. "Java Version")
	  btn-os-name (JButton. "OS Name")
	  btn-os-arch (JButton. "OS Architecture")
	  btn-current-working-dir (JButton. "Current working directory")
	  btn-resize-to-default (JButton. "Resize to default")
	  btn-clear-all (JButton. "Clear")]
      (do
	;; add button-listener to all buttons
	(doto-each  [btn [btn-java-cp
			  btn-java-version
			  btn-os-name
			  btn-os-arch
			  btn-current-working-dir
			  btn-resize-to-default
			  btn-clear-all]]
 
		      ;; add listener to button
		    (.addActionListener
		     (button-listener (get *label-property-mappings* (.getText btn)) label-content frame))))
 
	;; add buttons to panel
	(add-each panel-left
		  [btn-java-cp
		   btn-java-version
		   btn-os-name
		   btn-os-arch
		   btn-current-working-dir])
	(add-each panel-south
		  [btn-resize-to-default
		   btn-clear-all])
 
	;; add labels to panel
	(add-each panel-header
		  [label-header
		   label-blank])
	(.add panel-south label-adztec-indep)
 
	;; pack on frame
	(let [content-pane (.getContentPane frame)]
	  (add-each content-pane
		    [panel-main
		     label-content])
	  (doto content-pane
	    (.add BorderLayout/NORTH panel-header)
	    (.add BorderLayout/WEST panel-left)
	    (.add BorderLayout/SOUTH panel-south)))
	(doto frame
	  (.pack)
	  (.setTitle *prog-name*)
	  (resize-frame *x-coord* *y-coord* *width* *height*)
	  (.setVisible *visible*)
	  (.setResizable *resizable*)
	  (.setDefaultCloseOperation JFrame/HIDE_ON_CLOSE)))
    frame)) ;; return frame
 
 
(defn -main
  "Main function. Gets called by the system, if used as an executable .jar file."
  []
  (let [*frame* (create-new-sysinfo-window)]
       (. Thread (sleep 100))))

Posted in General. Tagged with , , , , , , , , , , .

One Response

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Hey, die System Properties sehen echt genau so aus wie die in Java geschriebenen (ist ja auch quasi Java ;) )
    Schon cool!

Some HTML is OK

(required)

(required, but never shared)

or, reply to this post via trackback.


Ihr Browser versucht gerade eine Seite aus dem sogenannten Internet auszudrucken. Das Internet ist ein weltweites Netzwerk von Computern, das den Menschen ganz neue Möglichkeiten der Kommunikation bietet.

Da Politiker im Regelfall von neuen Dingen nichts verstehen, halten wir es für notwendig, sie davor zu schützen. Dies ist im beidseitigen Interesse, da unnötige Angstzustände bei Ihnen verhindert werden, ebenso wie es uns vor profilierungs- und machtsüchtigen Politikern schützt.

Sollten Sie der Meinung sein, dass Sie diese Internetseite dennoch sehen sollten, so können Sie jederzeit durch normalen Gebrauch eines Internetbrowsers darauf zugreifen. Dazu sind aber minimale Computerkenntnisse erforderlich. Sollten Sie diese nicht haben, vergessen Sie einfach dieses Internet und lassen uns in Ruhe.

Die Umgehung dieser Ausdrucksperre ist nach §95a UrhG verboten.

Mehr Informationen unter www.politiker-stopp.de.