【问题标题】:Race condition (?) when using Swing使用 Swing 时的竞争条件 (?)
【发布时间】:2010-07-29 21:01:53
【问题描述】:

我已经从尝试通过 Penumbra 使用 OpenGL 转向尝试使用其 Graphics 上下文直接在 JPanel 上绘图。

这会很好,除非我遇到了一些麻烦……我编译了我的代码,并且在 25 次中大约有 1 次,图形(示例中是一个矩形)绘制得很好。其他约 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。我很困惑。

像往常一样,我们将不胜感激。我希望这是一个有答案的问题!最近,我似乎在问不可能的事情:)

【问题讨论】:

    标签: java swing clojure race-condition


    【解决方案1】:

    确保您始终在 EDT 上。如果您看到您的 GUI 随机运行,这通常是原因。竞态条件对于 swing 至关重要,因为它被设计为完全单线程的。

    你可能会尝试,只是为了看看,找到任何与摆动组件交互的方法,并让它打印出 Thread.getCurrentThread().toString()(或非常接近的东西)。

    它应该总是打印出一个线程名称,并且您会在某处看到嵌入的字母 AWT。您甚至可以存储该线程,在每次调用 Swing 时对其进行测试,并断言它是否不同。

    实际上我不知道为什么 Sun 从来没有构建一个“调试”版本的 JDK,当这样的事情发生时会断言(比如从非 awt 线程调用某个摆动线程时......)

    【讨论】:

    • 太棒了,谢谢!关于从哪里开始的任何建议? (而且,对于奖励积分,知道我可能在哪里偏离了 EDT 吗?)
    • 恐怕我对您正在使用的框架了解得不够多——我不认识语法,只能说它是声明性的。您可以做的一件(烦人的)事情是将您使用的所有控件子类化,覆盖您可能使用的方法并让它们输出当前线程。另一种可能性是在画线的头部打印出该线程名称并查看它是否包含字母 AWT。不过在那之后,我只是对你的代码知之甚少。
    【解决方案2】:

    您应该在面板中覆盖paintComponent。 (JPanel 的选择可能不是最好的 - 使用 JComponent 和某些 set-opaque。)

    另外,我猜你应该在 AWT EDT。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-12
      • 2019-02-10
      • 2015-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-10
      相关资源
      最近更新 更多