1

I am trying to write a clojure code which generates an Image with each pixel of image having a value of XOR of its x and y co-ordinates but I am getting a NullpointerException. I am not able to figure out what is going wrong in my code

Here is my code:

(ns com.test
  (:import (javax.swing JFrame))
  (:gen-class))


; Each pixel has color value of xor of its x and y co-ordinates
(defn generateXorList [limit]
  (for [x (range limit)
        y (range limit)]
    [x y (bit-xor x y)]
))


(defn makeImage [seq]
  (let [frameSize 250
        frame (JFrame.)
        gfx (.getGraphics frame)]    
    (.setVisible frame true)
    (.setSize frame frameSize frameSize)
    (.setDefaultCloseOperation frame JFrame/EXIT_ON_CLOSE)
    (doseq [[x y color] seq]      
      (.setColor gfx (java.awt.Color. color))
      (.fillRect gfx x y 1 1)
      )))

;; Generate the image
(makeImage (generateXorList 250))

Here is the stacktrace

clojure.lang.Compiler$CompilerException: java.lang.NullPointerException, compiling:(/tmp/t.clj:26:1)
 at clojure.lang.Compiler.load (Compiler.java:7239)
    user$eval1125.invoke (form-init5557027396137860263.clj:1)
    clojure.lang.Compiler.eval (Compiler.java:6782)
    clojure.lang.Compiler.eval (Compiler.java:6745)
    clojure.core$eval.invoke (core.clj:3081)
    clojure.main$repl$read_eval_print__7099$fn__7102.invoke (main.clj:240)
    clojure.main$repl$read_eval_print__7099.invoke (main.clj:240)
    clojure.main$repl$fn__7108.invoke (main.clj:258)
    clojure.main$repl.doInvoke (main.clj:258)
    clojure.lang.RestFn.invoke (RestFn.java:1523)
    clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__623.invoke (interruptible_eval.clj:58)
    clojure.lang.AFn.applyToHelper (AFn.java:152)
    clojure.lang.AFn.applyTo (AFn.java:144)
    clojure.core$apply.invoke (core.clj:630)
    clojure.core$with_bindings_STAR_.doInvoke (core.clj:1868)
    clojure.lang.RestFn.invoke (RestFn.java:425)
    clojure.tools.nrepl.middleware.interruptible_eval$evaluate.invoke (interruptible_eval.clj:56)
    clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__665$fn__668.invoke (interruptible_eval.clj:191)
    clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__660.invoke (interruptible_eval.clj:159)
    clojure.lang.AFn.run (AFn.java:22)
    java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1142)
    java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:617)
    java.lang.Thread.run (Thread.java:745)
Caused by: java.lang.NullPointerException: null
 at com.test$makeImage.invoke (t.clj:22)
    com.test$eval1171.invoke (t.clj:27)
    clojure.lang.Compiler.eval (Compiler.java:6782)
    clojure.lang.Compiler.load (Compiler.java:7227)
    user$eval1125.invoke (form-init5557027396137860263.clj:1)
    clojure.lang.Compiler.eval (Compiler.java:6782)
    clojure.lang.Compiler.eval (Compiler.java:6745)
    clojure.core$eval.invoke (core.clj:3081)
    clojure.main$repl$read_eval_print__7099$fn__7102.invoke (main.clj:240)
    clojure.main$repl$read_eval_print__7099.invoke (main.clj:240)
    clojure.main$repl$fn__7108.invoke (main.clj:258)
    clojure.main$repl.doInvoke (main.clj:258)
    clojure.lang.RestFn.invoke (RestFn.java:1523)
    clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__623.invoke (interruptible_eval.clj:58)
    clojure.lang.AFn.applyToHelper (AFn.java:152)
    clojure.lang.AFn.applyTo (AFn.java:144)
    clojure.core$apply.invoke (core.clj:630)
    clojure.core$with_bindings_STAR_.doInvoke (core.clj:1868)
    clojure.lang.RestFn.invoke (RestFn.java:425)
    clojure.tools.nrepl.middleware.interruptible_eval$evaluate.invoke (interruptible_eval.clj:56)
    clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__665$fn__668.invoke (interruptible_eval.clj:191)
    clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__660.invoke (interruptible_eval.clj:159)
    clojure.lang.AFn.run (AFn.java:22)
    java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1142)
    java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:617)
    java.lang.Thread.run (Thread.java:745)
1
  • Please, attach the stacktrace of NullPointerException thrown. Commented Jun 1, 2016 at 9:28

1 Answer 1

6

JFrame.getGraphics will return null until the frame is visible:

Creates a graphics context for this component. This method will return null if this component is currently not displayable.

You have to first call (.setVisible frame true) before calling (.getGraphics frame) and assigning it to a local variable.

(defn makeImage [seq]
  (let [frameSize 250
        frame (JFrame.)]
    (.setVisible frame true)
    (.setSize frame frameSize frameSize)
    (.setDefaultCloseOperation frame JFrame/EXIT_ON_CLOSE)
    (let [gfx (.getGraphics frame)]
      (doseq [[x y color] seq]      
        (.setColor gfx (java.awt.Color. color))
        (.fillRect gfx x y 1 1)))))

or setup your frame using doto:

(defn makeImage [seq]
  (let [frameSize 250
        frame (doto (JFrame.)
                (.setVisible true)
                (.setSize frameSize frameSize)
                (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE))
        gfx (.getGraphics frame)]    
    (doseq [[x y color] seq]      
      (.setColor gfx (java.awt.Color. color))
      (.fillRect gfx x y 1 1))))
Sign up to request clarification or add additional context in comments.

7 Comments

how do I assign it to a local variable?
Please, look at the enhanced answer.
Thanks for the answer! One question.. which approach should I prefer? 1st or 2nd?
In this particular case I prefer doto as it encapsulates the whole setup of an object before I can use it. I would even consider extracting this part into a separate function so that makeImage responsibility is only "making an image" and not setting up a frame.
As you work with Swing in Clojure you might be interested in seesaw project which provides friendly Clojure API for Swing.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.