2010-07-29 16 views
6

Ich habe versucht, OpenGL durch Penumbra zu verwenden, um zu versuchen, direkt auf einem JPanel mit seinem Grafikkontext zu zeichnen.Race condition (?) Bei Verwendung von Swing

Das wäre toll, außer dass ich in Schwierigkeiten gerate ... Ich kompiliere meinen Code, und ~ 1 Mal von 25, die Grafik (es ist ein Rechteck für das Beispiel) zeichnet gut. Der andere ~ 24 mal, tut es nicht.

Hier ist mein Code:

(def main 
    (let [frame (JFrame. "This is a test.") 
     main-panel (JPanel. (GridBagLayout.)) 
     tpan (proxy [JPanel] [] (getPreferredSize [] (Dimension. 600 400)))] 

    (doto frame 
     (set-content-pane 
     (doto main-panel 
     (grid-bag-layout 
      :gridx 0 :gridy 0 
      tpan 
      :gridx 0 :gridy 1 
      xy-label))) 
     (pack-frame) 
     (set-visible)) 

    (draw-line tpan Color/RED 250 250 50 50))) 

Die Funktion draw-line ist unten:

(defn draw-line [panel color x y w h] 
    (let [graphics (.getGraphics panel)] 
    (doto graphics 
     (.setColor color) 
     (.drawRect x y w h)))) 

Ich habe keine Ahnung, was los ist. Zuerst dachte ich, es wären die Refs, an denen ich gearbeitet habe, aber dann habe ich diese rausgenommen und habe immer noch diese Probleme. Ich habe auch lein und slime/swank und emacs zurückgesetzt. Ich bin ziemlich verwirrt.

Wie üblich, jede Hilfe wäre willkommen. Ich hoffe, das ist eine Frage mit einer Antwort! In letzter Zeit, ich scheine das Unmögliche zu fragen :)

Antwort

5

Stellen Sie sicher, dass Sie immer auf dem EDT sind. Wenn Sie sehen, dass Ihre GUI zufällig funktioniert, ist dies in der Regel die Ursache. Race-Bedingungen sind kritisch für den Swing, da sie vollständig single-threaded sind.

Was Sie versuchen könnten, nur um zu sehen, ist jede Methode zu finden, die mit einer Swing-Komponente interagiert und die Thread.getCurrentThread(). ToString() (oder etwas sehr ähnliches) ausgeben lässt.

Es sollte immer einen Thread-Namen ausdrucken und Sie werden die Buchstaben AWT dort irgendwo eingebettet sehen. Sie könnten sogar diesen Thread speichern, bei jedem Aufruf in Swing dagegen testen und feststellen, ob es nicht derselbe ist.

Eigentlich weiß ich nicht, warum Sun nie eine „Debug“ Version des JDK gebaut, die behaupten würden, wenn Dinge wie das passiert ist (wie wenn einiger Swing-Thread von einem Nicht-AWT-Thread aufgerufen wurde ...)

+0

Fantastisch, danke! Irgendwelche Vorschläge, wo man anfangen soll? (Und, für Bonuspunkte, irgendeine Idee, wo ich vom EDT abweichen könnte?) – Isaac

+0

Ich fürchte, ich weiß nicht genug über das Framework, das Sie verwenden - ich erkenne die Syntax nicht, außer in der Lage zu sein sag, dass es deklarativ ist. Eine (nervige) Sache, die Sie tun könnten, ist die Unterklasse aller von Ihnen verwendeten Steuerelemente, überschreiben Sie die Methoden, die Sie verwenden könnten, und lassen Sie sie den aktuellen Thread ausgeben. Eine andere Möglichkeit ist, an der Spitze der Zeichnungslinie den Namen des Threads auszudrucken und zu sehen, ob er die Buchstaben AWT enthält. Danach weiß ich einfach nicht genug über deinen Code. –

4

Sie sollten paintComponent im Panel überschreiben. (Wahl von JPanel ist wahrscheinlich nicht die beste - verwenden Sie JComponent und bestimmte set-opaque darauf.)

Auch ich denke, Sie sollten auf der AWT EDT sein.

Verwandte Themen