2010-07-29 9 views
6

Je suis passé d'essayer d'utiliser OpenGL à Penumbra pour essayer de dessiner directement sur un JPanel en utilisant son contexte graphique.Condition de course (?) Lors de l'utilisation de Swing

Ce serait génial, sauf que je rencontre des problèmes ... Je compile mon code, et ~ 1 fois sur 25, le graphique (c'est un rectangle pour l'exemple) dessine très bien. L'autre ~ 24 fois, ce n'est pas le cas.

Voici mon 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))) 

La fonction est draw-line ci-dessous:

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

Je ne sais pas ce qui se passe. Au début, je pensais que c'était sur les refs sur lesquels je travaillais, mais ensuite je les ai enlevés, et j'ai toujours ces problèmes. J'ai réinitialisé lein et slime/swank et emacs, aussi. Je suis assez perplexe.

Comme d'habitude, n'importe quelle aide serait appréciée. J'espère que c'est une question avec une réponse! Dernièrement, je semble demander l'impossible :)

Répondre

5

Vérifiez que vous êtes toujours sur l'EDT. Si vous voyez votre GUI agir au hasard, c'est généralement la cause. Les conditions de course sont essentielles au swing car elles sont conçues pour être entièrement monotrou. Qu'est-ce que vous pourriez essayer, juste pour voir, est de trouver une méthode qui interagit avec un composant swing et le faire imprimer le Thread.getCurrentThread(). ToString() (ou quelque chose de très proche de cela).

Il devrait toujours afficher un nom de fil et vous verrez les lettres AWT incorporées quelque part. Vous pouvez même stocker ce fil, le tester à chaque appel dans Swing et affirmer que ce n'est pas la même chose.

En fait, je ne sais pas pourquoi la version du Sun JDK n'a jamais construit un « Debug » qui affirmerait quand les choses se sont passées comme ça (comme quand un fil swing a été appelé à partir d'un fil non AWT ...)

+0

Fantastique, merci! Des suggestions sur où commencer? (Et, pour les points bonus, toute idée où je pourrais m'écarter de l'EDT?) – Isaac

+0

Je crains de ne pas en savoir assez sur le framework que vous utilisez - je ne reconnais pas la syntaxe sauf pour pouvoir dites que c'est déclaratif. Une chose (ennuyante) que vous pourriez faire est de sous-classer tous les contrôles que vous utilisez, de remplacer les méthodes que vous pourriez utiliser et de les faire sortir le thread en cours. Une autre possibilité est à la tête de draw-line d'imprimer ce nom de thread et de voir s'il contient les lettres AWT. Après cela, je n'en sais pas assez sur votre code. –

4

Vous devez écraser paintComponent dans le panneau. (Le choix de JPanel n'est probablement pas le meilleur - utilisez JComponent et certains set-opaque dessus.)

Aussi, je suppose que vous devriez être sur l'AWT EDT.

Questions connexes