【问题标题】:How does Swing handle consecutive changes to the same component?Swing 如何处理对同一组件的连续更改?
【发布时间】:2023-04-02 22:01:01
【问题描述】:

我对 Swing 绘画模型有点困惑。

假设我有一个 JComponent 组件,并且我执行以下操作:

c.setBackground(Color.RED);
c.setBackground(Color.YELLOW);

显然,最终的结果是颜色是黄色的。

Swing 如何处理这个问题?

第一次调用是否会触发立即重绘,所以在黄色之前会有短暂的红色闪烁?这个序列是不是比仅仅涂上一层黄色要慢得多?

如果我从 Swing Event 线程之外运行它,我会假设在大多数情况下(尽管可能出现竞争条件),当 Swing EDT 访问该属性时,该属性已设置为黄色,因此将永远不要被涂成红色。

但是,我的理解是我应该从 Swing EDT 中的 Runnable 内部进行这些调用。那是对的吗?在这种情况下,EDT 似乎必须在没有任何“前瞻”的情况下完全执行每个更改?

【问题讨论】:

    标签: java performance swing


    【解决方案1】:

    窗口区域立即被标记为脏。油漆请求稍后将在 EDT 上返回。操作系统或事件队列机制(甚至组件)可能会合并重绘事件(严格来说是实现的质量问题,但实际上在同一窗口中的重绘将被合并,即使它们不相交)。

    应在 EDT 上调用 Swing 组件上的方法。 Event Dispatch Thread 属于 AWT,而不是 Swing。

    【讨论】:

    • 汤姆,我有点困惑。如果我在invokeLater() 或invokeAndWait() 中运行这两个命令,它们中的每一个不会立即发生吗?还是 Swing 在 EDT 上添加了带有自己的指令的额外 invokeLaters() ?另外,EDT 和 AWT 调度线程是一样的吗?
    • 如果你在 invokeLater 中运行,整个代码块(在 Runnable 中)将在 EDT 上执行。见我上面的回复
    • 如果您使用invokeLater/invokeAndWait,该命令将排队并在与绘画相同的线程上执行。 invokeLater/invokeAndWait 只需将 InvocationEvent 添加到 AWT EventQueue
    【解决方案2】:

    首先,您不应该在 EDT 之外拨打此类电话。结果可能无法预测。 由于所有 Swing 组件都是双缓冲的,因此您在执行此操作时不会看到闪烁。除此之外,所有连续的重绘请求都尽可能合并为一个。

    总的来说,只要在 EDT 上完成,您应该不会看到任何问题

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-22
      • 2012-04-05
      • 1970-01-01
      • 2012-09-27
      • 2020-06-30
      • 1970-01-01
      相关资源
      最近更新 更多