Состояние гонки (?) При использовании Swing - PullRequest
6 голосов
/ 30 июля 2010

Я перешел от попытки использовать OpenGL через Penumbra к попытке рисовать непосредственно на JPanel с использованием ее графического контекста.

Это было бы здорово, за исключением того, что у меня возникли некоторые проблемы ... Я компилирую свой код, и ~ 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 тоже.Я очень озадачен.

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

Ответы [ 2 ]

5 голосов
/ 30 июля 2010

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

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

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

На самом деле я не знаю, почему Sun никогда не создавала версию JDK "Debug", которая быутверждать, когда происходили подобные вещи (например, когда какой-то поток качания был вызван из не-awt-потока ...)

4 голосов
/ 30 июля 2010

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

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

...