2009-10-05 4 views
7

! Swing/Clojure에서 이미지 프로세싱 애플리케이션을 만들고 있는데, 지금은 데이터를 클릭하고 계산할 수있는 이미지 패널을 개발해야합니다. coobird 덕택에, 나는 자바에서 그것을하는 방법에 대한 좋은 생각을 가지고있다. 그러나 나는 여전히 Clojure와의 통합에 많은 이슈를 얻지 못한다.이미지 처리, JPanel 확장 및 Clojure에서의 시뮬레이션 클래스

coobird가 나에게 제안한 방법을 살펴 보겠습니다. 먼저 Java로 클래스를 확장해야합니다. Clojure에, 우리는 매크로 proxy이 작업을 수행, 그래서 우리는이 같은 거라고 :

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

다음 단계는 클래스 생성자를 생성하고 몇 가지 변수를 설정하는 것입니다.

  1. 나는 프록시의 두 번째 인수 후에 함수를 정의 할 수 있지만, 어떻게 생성자를 만들 수 있습니까? 페인팅 패널은이 클래스의 이름입니까 (그러므로 내가 작성해야하는 함수의 이름)?

  2. 어떻게 클래스 변수를 다룰 수 있습니까? 내가 그런 것처럼 let으로 정의해야합니까?

  3. 아래와 같이 사용하려면 thissuper을 사용할 수 있습니까?

 
(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))))))))) 

제안 및 코드 수정도 환영합니다!

감사합니다.

답변

8
  1. 프록시가 실제로 인스턴스를 만듭니다. tada! 생성자를 만들 필요가 없습니다.

  2. 예, 대신 클로져를 사용하는 것이 좋습니다. 또한 두 번째 마지막 줄에있는 것과 같은 def를 사용하는 것은 지저분합니다! 당신의 로직이 let에 의해 생성 된 어휘 적 스코프에 의존 할 때 포인트 - 클릭을위한 글로벌 바인딩을 생성합니다.

  3. (프록시 슈퍼의 paintComponent의 g), 및 예 "이"

이 있습니다 나를 위해 작동합니다

(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

내가 사람을 당신을 사랑합니다. 진지하게. – konr

+3

나는 너를 너무 사랑해. –