# BufferStrategy 和 BufferCapabilities

> 原文： [https://docs.oracle.com/javase/tutorial/extra/fullscreen/bufferstrategy.html](https://docs.oracle.com/javase/tutorial/extra/fullscreen/bufferstrategy.html)

## `BufferStrategy`

在 Java 2 Standard Edition 中，您不必担心视频指针或视频内存，以便充分利用双缓冲或页面翻转。添加了新类 `java.awt.image.BufferStrategy` 是为了便于以一般方式处理绘制到曲面和组件，无论使用的缓冲区数量或用于显示它们的技术如何。

缓冲策略为您提供了两种通用的绘图方法： `getDrawGraphics` 和 `show` 。当您想要开始绘图时，获取绘制图形并使用它。当您完成绘图并想要将信息显示在屏幕上时，请调用 `show` 。这两种方法旨在相当优雅地适应渲染循环：

```
BufferStrategy myStrategy;

while (!done) {
    Graphics g = myStrategy.getDrawGraphics();
    render(g);
    g.dispose();
    myStrategy.show();
}

```

还设置了缓冲策略来帮助您监控 `VolatileImage` 问题。在全屏独占模式下， `VolatileImage` 问题尤其重要，因为窗口系统有时可以收回它给你的视频内存。一个重要的例子是当用户在 Windows 中按下 `ALT + TAB` 组合键时 - 突然你的全屏程序在后台运行，你的视频内存丢失了。您可以调用 `contentsLost` 方法来查明是否发生了这种情况。同样，当窗口系统将内存返回给您时，您可以找到使用 `contentsRestored` 方法。

## `BufferCapabilities`

如前所述，不同的操作系统，甚至同一操作系统上的不同图形卡，可以使用不同的技术。这些 _ 功能 _ 为您提供，以便您可以为您的应用选择最佳技术。

类 `java.awt.BufferCapabilities` 封装了这些功能。每个缓冲区策略都由其缓冲区功能控制，因此为您的应用选择正确的缓冲区非常重要。要找出可用的功能，请从图形设备上可用的 `GraphicsConfiguration` 对象中调用 `getBufferCapabilities` 方法。

Java 2 Standard Edition 1.4 版中提供的功能包括：

*   `isPageFlipping`
    此功能返回此图形配置上是否有硬件页面翻转。
*   `isFullScreenRequired`
    此功能返回在尝试硬件页面翻转之前是否需要全屏独占模式。
*   `isMultiBufferAvailable`
    此功能返回硬件中是否有多个缓冲（两个或多个后缓冲区加上主表面）可用。
*   `getFlipContents`
    此功能返回用于执行硬件页面翻转的技术的提示。这很重要，因为`显示`后的后缓冲液的含量根据使用的技术而不同。返回的值可以为 null（如果 `isPageFlipping` 返回 `false` ）或以下值之一。只要 `isPageFlipping` 方法返回 true，就可以为缓冲区策略指定任何值，但性能会因可用功能而异。
*   `FlipContents.COPIED`
    该值表示后缓冲区的内容被复制到主表面。 “翻转”可能是作为硬件 blt 执行的，这意味着硬件双缓冲可能是使用 blitting 而不是真正的页面翻转来完成的。这应该（理论上）比 `VolatileImage` 到主表面的速度更快，或者至少同样快，尽管你的里程可能会有所不同。后缓冲器的内容与翻转后的主表面相同。
*   `FlipContents.BACKGROUND`
    该值表示已使用背景颜色清除后缓冲区的内容。无论是真正的页面翻转还是 blt 都发生了。
*   `FlipContents.PRIOR`
    此值表示后缓冲区的内容现在是旧主曲面的内容，反之亦然。通常，此值表示发生了真正的页面翻转，但这不能保证，并且再一次，您在此操作上的里程可能会有所不同。
*   `FlipContents.UNKNOWN`
    该值表示翻转后后缓冲区的内容未定义。您可能需要尝试找到最适合您的技术（或者您可能不关心），并且每次绘制时您必须自己设置后备缓冲区的内容。

要为组件创建缓冲区策略，请调用 `createBufferStrategy` 方法，提供所需的缓冲区数（此数字包括主表面）。如果需要任何特定的缓冲技术，请提供适当的 `BufferCapabilities` 对象。请注意，当您使用此版本的方法时，如果您的选择不可用，则必须捕获 `AWTException` 。另请注意，这些方法仅适用于 `Canvas` 和 `Window` 。

一旦为组件创建了特定的缓冲区策略，就可以使用 `getBufferStrategy` 方法对其进行操作。请注意，此方法也仅适用于画布和窗口。

## 编程技巧

关于使用缓冲功能和缓冲策略的一些提示：

*   获取，使用和处理图形对象在`尝试...最终`子句中更加强大：

    ```
    BufferStrategy myStrategy;

    while (!done) {
        Graphics g;
        try {
            g = myStrategy.getDrawGraphics();
            render(g);
        } finally {
            g.dispose();
        }
        myStrategy.show();
    }

    ```

*   在使用缓冲策略之前检查可用功能。
*   为获得最佳效果，请在全屏独占窗口上创建缓冲区策略。在使用页面翻转之前，请确保检查 `isFullScreenRequired` 和 `isPageFlipping` 功能。
*   不要对性能做任何假设。根据需要调整代码，但请记住，不同的操作系统和图形卡具有不同的功能。描述您的应用！
*   您可能希望子组化您的组件以覆盖 `createBufferStrategy` 方法。使用算法选择最适合您的应用程序的策略。 `FlipBufferStrategy` 和 `BltBufferStrategy` 内部类受到保护，可以进行子类化。
*   不要忘记你可能会丢失你的绘图表面！在绘图之前一定要检查 `contentsLost` 和 `contentsRestored` 。丢失的所有缓冲区在恢复时都必须重绘。
*   如果在 Swing 应用程序中使用缓冲策略进行双缓冲，则可能需要关闭 Swing 组件的双缓冲，因为它们已经是双缓冲的。视频内存有些宝贵，只应在绝对必要时使用。
*   使用多个后备缓冲区可能最终会浪费。多次缓冲仅在绘图时间超过执行`节目`所花费的时间时有用。描述您的应用！