2010-07-29 4 views
6

Я перешел от использования OpenGL через Penumbra к попытке рисовать непосредственно на JPanel, используя его графический контекст.Состояние гонки (?) При использовании Swing

Это было бы здорово, если бы у меня не возникало проблем ... Я скомпилирую свой код и ~ 1 раз из 25, графический (это прямоугольник для примера) рисует просто отлично. Другой ~ 24 раза, это не так.

Вот мой код:

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

Функция draw-line ниже:

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

Я понятия не имею, что происходит. Сначала я подумал, что это были ссылки, над которыми я работал, но потом я их вытащил и все еще имею эти проблемы. Я сбросил lein и slime/swank и emacs. Я очень озадачен.

Как обычно, любая помощь будет оценена по достоинству. Надеюсь, это вопрос с ответом! В последнее время я, кажется, задаю невозможное :)

ответ

5

Убедитесь, что вы всегда находитесь на EDT. Если вы видите, что ваш графический интерфейс работает случайным образом, что обычно является причиной. Условия гонки имеют решающее значение для качания, потому что он разработан полностью однопоточным.

Что вы можете попробовать, просто чтобы увидеть, найти любой метод, который взаимодействует с компонентом swing и распечатать Thread.getCurrentThread(). ToString() (или что-то очень близкое к этому).

Он должен всегда распечатывать имя потока, и вы увидите буквы AWT, встроенные там где-то. Вы можете даже сохранить этот поток, протестировать его при каждом вызове в Swing и утверждать, если это не одно и то же.

На самом деле я не знаю, почему ВС никогда не построили «Debug» версию JDK, который будет утверждать, когда такие вещи, как это произошло (например, когда некоторые свинг нить была вызвана не-АВТ нить ...)

+0

Фантастический, спасибо! Любые предложения о том, с чего начать? (И, для бонусов, любая идея, где я мог бы отклониться от EDT?) – Isaac

+0

Боюсь, я недостаточно знаю об используемой структуре - я не понимаю синтаксис, кроме как иметь возможность скажите, что он декларативный. Одна (раздражающая) вещь, которую вы могли бы сделать, - это подкласс всех используемых вами элементов управления, переопределить методы, которые вы можете использовать, и заставить их выводить текущий поток. Другая возможность заключается во вводе строки, чтобы распечатать это имя потока и посмотреть, содержит ли он буквы AWT. Однако после этого я просто не знаю достаточно о вашем коде. –

4

Вы должны быть переопределены paintComponent на панели. (Выбор JPanel, вероятно, не самый лучший. - использовать JComponent и определенную set-opaque на нем)

Кроме того, я думаю, вы должны быть на AWT EDT.

Смежные вопросы