2009-10-05 5 views
7

dort! Ich baue gerade eine Bildverarbeitungsanwendung in Swing/Clojure, und jetzt muss ich ein Bildfenster entwickeln, in dem ich Daten anklicken und berechnen kann. Dank coobird habe ich jetzt eine gute Idee, wie man es in Java macht, aber ich bekomme immer noch nicht viele Probleme bei der Integration mit Clojure.Bildverarbeitung, Erweiterung JPanel und Simulationsklassen in Clojure

Werfen wir einen Blick darauf, wie Cookbird mich vorgeschlagen hat. Zuerst sollten wir eine Klasse in Java erweitern. In clojure, tun wir dies mit dem proxy Makro, so würden wir so etwas wie dieses:

 
(def painting-panel 
    (proxy [JPanel] [])) 

Der nächste Schritt ist es, den Konstruktor der Klasse zu erstellen und einige Variablen gesetzt.

  1. I Funktionen nach dem zweiten Argument von Proxy definieren kann, aber wie kann ich den Konstruktor erstellen? Ist painting-panel der Name dieser Klasse (daher der Name der Funktion, die ich erstellen soll)?

  2. Wie kann ich mit Klassenvariablen umgehen? Sollte ich sie mit einer let definieren, wie ich es getan habe?

  3. Sind this und super für mich verfügbar, wie ich unten getan habe?

 
(def painting-panel 
    (let [background-image (Image.) 
      point-clicked (Point.)] 
    (proxy [JPanel] [] 
     (paintComponent [g] 
      (do ((.paintComponent super) g) 
      (doto g 
       (.drawImage background-image 0 0 nil) 
       (.fillRect (.x point-clicked) (.y point-clicked) 1 1)))) 
     (painting-panel []; constructor? 
      ((.addMouseListener this) 
      (proxy [MouseAdapter] [] 
       (mouseClicked [e] 
       (do 
        (def point-clicked (.getPoint e)) 
        (.repaint this))))))))) 

Vorschläge und Code-Korrekturen sind auch willkommen!

Vielen Dank!

Antwort

8
  1. Proxy erstellt tatsächlich eine Instanz Tada! Sie müssen keinen Konstruktor erstellen.

  2. Ja, aber verwenden Sie stattdessen einen Clojure Ref. Auch def auf der zweitletzten Zeile zu benutzen ist fies! Es erstellt eine globale Bindung für einen Punktklick, wenn Ihre Logik auf dem lexikalischen Bereich basiert, der von let erstellt wurde.

  3. (Proxy-super paintcomponent g), und ja "this" ist verfügbar

Dies funktioniert für mich:

(let [click (ref nil) 
     panel (proxy [javax.swing.JPanel] [] 
       (paintComponent [g] 
       (proxy-super paintComponent g) 
       (.drawImage g (.getImage 
          (javax.swing.ImageIcon. "play.png")) 
          0 0 (.getWidth this) (.getHeight this) nil) 
       (if @click 
        (.fillRect g (:x @click) (:y @click) 10 10))))] 
    (.addMouseListener panel 
     (proxy [java.awt.event.MouseAdapter] [] 
     (mouseClicked [e] 
      (let [p (.getPoint e)] 
      (dosync (ref-set click {:x (.x p), :y (.y p)}))) 
      (javax.swing.SwingUtilities/invokeLater #(.repaint panel))))) 
    (doto (javax.swing.JFrame.) 
    (.setContentPane panel) 
    (.setSize 200 200) 
    (.show))) 
+1

Ich liebe dich, Jungs. Ernst. – konr

+3

Ich liebe dich auch. –