# 显示自定义加载进度指示器

> 原文： [https://docs.oracle.com/javase/tutorial/deployment/applet/customProgressIndicatorForApplet.html](https://docs.oracle.com/javase/tutorial/deployment/applet/customProgressIndicatorForApplet.html)

Java applet 可以显示自定义加载进度指示器，该指示器显示 applet 资源的下载进度以及其他 applet 特定数据。

考虑 Weather applet 和`CustomProgress`类，以了解如何为 Java applet 实现自定义加载进度指示器。为了演示大量且长时间的下载，此 applet 的 JAR 文件已被人工膨胀，`customprogress_applet.jnlp`文件将其他 JAR 文件指定为资源。

## 开发定制的加载进度指标

要为 applet 开发自定义加载进度指示器，请创建一个实现 [`DownloadServiceListener`](https://docs.oracle.com/javase/8/docs/jre/api/javaws/jnlp/javax/jnlp/DownloadServiceListener.html) 接口的类。

加载进度指示器类的构造函数将根据 UI 的显示方式和类所需的功能而有所不同。应适用以下准则：

*   要在单独的顶级窗口中显示加载进度指示器，请创建一个没有任何参数的构造函数。
*   要在 applet 的容器​​中显示 applet 的加载进度指示器，请创建一个以`Object`作为参数的构造函数。 `Object`参数可以类型转换为 [`java.awt.Container`](https://docs.oracle.com/javase/8/docs/api/java/awt/Container.html) 类的实例。
*   If the loading progress indicator class needs to access the applet's parameters, create two constructors as follows:
    *   创建一个构造函数，将`Object`作为参数，如前所述。
    *   创建一个带有两个`Object`类型参数的构造函数。第一个参数可以是 [`java.awt.Container`](https://docs.oracle.com/javase/8/docs/api/java/awt/Container.html) 类的实例的类型转换，第二个参数可以类型转换为 [`java.applet.AppletStub`](https://docs.oracle.com/javase/8/docs/api/java/applet/AppletStub.html) 类的实例。

    Java Plug-in 软件将根据客户端计算机上 JRE 软件的功能调用相应的构造函数。

```
import javax.jnlp.DownloadServiceListener;
import java.awt.Container;
import java.applet.AppletStub;
import netscape.javascript.*;

// ...

public class CustomProgress implements DownloadServiceListener {   
    Container surfaceContainer = null;
    AppletStub appletStub = null;
    JProgressBar progressBar = null;
    JLabel statusLabel = null;
    boolean uiCreated = false;

    public CustomProgress(Object surface) {
       init(surface, null);
    }

    public CustomProgress(Object surface, Object stub) {
        init(surface, stub);
    }

    public void init(Object surface, Object stub) {
        try {
            surfaceContainer = (Container) surface;
            appletStub = (AppletStub) stub;
        } catch (ClassCastException cce) {
            // ...
        }
    }
// ...
}    

```

以下代码段显示了如何为加载进度指示器构建 UI。使用 [`java.applet.AppletStub`](https://docs.oracle.com/javase/8/docs/api/java/applet/AppletStub.html) 类的实例来检索 applet 的参数。调用`JSObject.getWindow(null)`方法以获取对 applet 的父网页的引用，并在该页面上调用 JavaScript 代码。

```
private void create() {
    JPanel top = createComponents();
    if (surfaceContainer != null) {
        // lay out loading progress UI in the given
        // Container
        surfaceContainer.add(top, BorderLayout.NORTH);
        surfaceContainer.invalidate();
        surfaceContainer.validate();
    }     
}
private JPanel createComponents() {
    JPanel top = new JPanel();
    // ...
    // get applet parameter using an instance of the
    // AppletStub class "tagLine" parameter specified
    // in applet's JNLP file
    String tagLine = "";
    if (appletStub != null) {
        tagLine = appletStub.getParameter("tagLine");
    }
    String lblText = "<html><font color=red size=+2>JDK
        Documentation</font><br/>" +
        tagLine + " <br/></html>";
    JLabel lbl = new JLabel(lblText);
    top.add(lbl, BorderLayout.NORTH);

    // use JSObject.getWindow(null) method to retrieve
    // a reference to the web page and make JavaScript
    // calls. Duke logo displayed if displayLogo variable
    // set to "true" in the web page
    String displayLogo = "false";    
    JSObject window = JSObject.getWindow(null);        
    if (window != null) {
        displayLogo = (String)window.getMember("displayLogo");
    }
    if (displayLogo.equals("true")) {
        lbl = new JLabel();
        ImageIcon logo = createImageIcon("images/DukeWave.gif", "logo");
        lbl.setIcon(logo);
        top.add(lbl, BorderLayout.EAST);
    }

    statusLabel = new JLabel(
        "html><font color=green size=-2>" +
        "Loading applet...</font></html>");
    top.add(statusLabel, BorderLayout.CENTER);

    // progress bar displays progress
    progressBar = new JProgressBar(0, 100);
    progressBar.setValue(0);
    progressBar.setStringPainted(true);
    top.add(progressBar, BorderLayout.SOUTH);

    return top;
}

```

根据`overallPercent`参数，在以下方法中创建和更新进度指示器。 Java Plug-in 软件定期调用这些方法来传达 applet 下载的进度。当资源下载和验证 100％完成时，Java 插件软件将始终发送消息。

```
public void progress(URL url, String version,
                     long readSoFar, long total,
                     int overallPercent) {        
    // check progress of download and update display
    updateProgressUI(overallPercent);
}

public void upgradingArchive(java.net.URL url,
                  java.lang.String version,
                  int patchPercent,
                  int overallPercent) {
    updateProgressUI(overallPercent);
}

public void validating(java.net.URL url,
            java.lang.String version,
            long entry,
            long total,
            int overallPercent) {
    updateProgressUI(overallPercent);
}

private void updateProgressUI(int overallPercent) {
    if (!uiCreated && overallPercent > 0
        && overallPercent < 100) {
        // create custom progress indicator's
        // UI only if there is more work to do,
        // meaning overallPercent > 0 and
        // < 100 this prevents flashing when
        // RIA is loaded from cache
        create(); 
        uiCreated = true;            
    }
    if (uiCreated) {
        progressBar.setValue(overallPercent);
    }
}

```

编译加载进度指示器类并使用显示加载进度指示器所需的所有资源构建 JAR 文件。在`classpath`中包含以下 JAR 文件以启用编译：

*   `&lt;your JRE directory&gt;/lib/javaws.jar`
*   `&lt;your JRE directory&gt;/lib/plugin.jar` - 仅当您的加载进度指示器类使用`JSObject.getWindow`方法在 applet 的父网页中调用 JavaScript 代码时，才需要此 JAR 文件。

加载进度指示器类现在可以使用了。下一步是将此加载进度指示器 JAR 文件指定为 applet 的加载进度指示器。

## 指定 Applet 的加载进度指示器

要为 applet 指定自定义加载进度指示器，请在 applet 的 JNLP 文件中包含以下信息：

*   带有`download="progress"`属性的`jar`标签
*   `progress-class`属性，带有加载进度类的完全限定名称。

[`customprogress_applet.jnlp`](examples/applet_AppletWithCustomProgressIndicator/src/customprogress_applet.jnlp) 文件中的以下代码片段显示`download="progress"`和`progress-class`属性的用法。

```
<jnlp spec="1.0+"
  codebase="https://docs.oracle.com/javase/tutorial/deployment"
  href="">
  <!-- ... -->
  <resources>
    <!-- ... -->
    <jar
      href="applet/examples/dist/applet_AppletWithCustomProgressIndicator"
      main="true" />    
    <jar
      href="applet/examples/dist/applet_CustomProgressIndicator/applet_CustomProgressIndicator.jar" 
     download="progress" />
  </resources>
  <applet-desc
     name="customprogressindicatordemo.WeatherApplet"
     main-class="customprogressindicatordemo.WeatherApplet"
     progress-class="customprogressindicator.CustomProgress"
     width="600"
     height="200">
     <param
       name="tagLine"
       value="Information straight from the horse's mouth!"/>
  </applet-desc>
<!-- ... -->
</jnlp>

```

在网页中部署 applet。在 Web 浏览器中打开 [`AppletPage.html`](examples/dist/applet_AppletWithCustomProgressIndicator/AppletPage.html) 以查看 Weather 小程序的加载进度指示器。

* * *

**Note:**  To view the example properly, you need to install at least the [Java SE Development Kit (JDK) 6 update 21](http://www.oracle.com/technetwork/java/javase/downloads/index.html) release.

* * *

* * *

**Note:** If you have viewed this applet before, clear your cache by using the Java Control Panel before viewing the applet again. You will not be able to see a progress indicator for a previously cached applet.

* * *

* * *

**Note:**  If you don't see the example running, you might need to enable the JavaScript interpreter in your browser so that the Deployment Toolkit script can function properly.

* * *

## 将加载进度指示器与 Applet UI 集成

您还可以将加载进度指示器集成到 applet 的 UI 中。在 Web 浏览器中打开 [`AppletPage.html`](examples/dist/applet_AppletWithIntegratedProgressIndicator/AppletPage.html) 以查看集成到 Weather applet 的 UI 中的加载进度指示器。查看 [`IntegratedProgressIndicator.java`](examples/applet_AppletWithIntegratedProgressIndicator/src/integratedprogressdemo/IntegratedProgressIndicator.java) 类和内联注释以获取更多信息。

下载以下示例的源代码以进一步试验：

*   [_ 小程序，带有自定义加载进度指示器 _](examplesIndex.html#AppletWithCustomProgressIndicator)
*   [_ 带有集成进度指示器的小程序 _](examplesIndex.html#AppletWithIntegratedProgressIndicator)

有关自定义富 Internet 应用程序（RIA）加载体验的详细信息，请参阅[自定义加载体验](../doingMoreWithRIA/customizeRIALoadingExperience.html)主题。