Java 中文官方教程 2022 版(十一)

2024-05-24 15:28:59 浏览数 (2)

模式类的方法

原文:docs.oracle.com/javase/tutorial/essential/regex/pattern.html

到目前为止,我们只使用测试工具来创建Pattern对象的最基本形式。本节探讨了一些高级技术,如使用标志创建模式和使用嵌入式标志表达式。它还探讨了一些我们尚未讨论的其他有用方法。

使用标志创建模式

Pattern类定义了一个替代的compile方法,接受一组影响模式匹配方式的标志。标志参数是一个位掩码,可以包括以下任何公共静态字段:

  • Pattern.CANON_EQ 启用规范等价性。当指定此标志时,只有当两个字符的完整规范分解匹配时,它们才被视为匹配。例如,表达式"au030A"将在指定此标志时匹配字符串"u00E5"。默认情况下,匹配不考虑规范等价性。指定此标志可能会带来性能损失。
  • Pattern.CASE_INSENSITIVE 启用不区分大小写的匹配。默认情况下,不区分大小写的匹配假定只有在 US-ASCII 字符集中的字符被匹配。通过与此标志一起指定 UNICODE_CASE 标志,可以启用 Unicode 感知的不区分大小写匹配。不区分大小写的匹配也可以通过嵌入式标志表达式(?i)启用。指定此标志可能会带来轻微的性能损失。
  • Pattern.COMMENTS 允许在模式中使用空格和注释。在此模式下,空格被忽略,并且以#开头的嵌入式注释被忽略直到行尾。注释模式也可以通过嵌入式标志表达式(?x)启用。
  • Pattern.DOTALL 启用 dotall 模式。在 dotall 模式下,表达式.匹配任何字符,包括行终止符。默认情况下,此表达式不匹配行终止符。Dotall 模式也可以通过嵌入式标志表达式(?s)启用。(s 是"single-line"模式的缩写,在 Perl 中称为这种模式。)
  • Pattern.LITERAL 启用模式的字面解析。当指定此标志时,指定模式的输入字符串被视为一系列字面字符。输入序列中的元字符或转义序列将不被赋予特殊含义。当与此标志一起使用时,CASE_INSENSITIVEUNICODE_CASE 标志在匹配时保留其影响。其他标志变得多余。没有嵌入式标志字符用于启用字面解析。
  • Pattern.MULTILINE 启用多行模式。在多行模式下,表达式^$分别在行终止符之后或之前匹配,或在输入序列的末尾。默认情况下,这些表达式仅在整个输入序列的开头和结尾匹配。多行模式也可以通过嵌入式标志表达式(?m)启用。
  • Pattern.UNICODE_CASE 启用 Unicode 感知大小写折叠。当指定此标志时,大小写不敏感匹配(由CASE_INSENSITIVE标志启用)将按照 Unicode 标准一致的方式进行。默认情况下,大小写不敏感匹配假定只匹配 US-ASCII 字符集中的字符。Unicode 感知大小写折叠也可以通过嵌入式标志表达式(?u)启用。指定此标志可能会带来性能损失。
  • Pattern.UNIX_LINES 启用 UNIX 行模式。在此模式下,只有'n'行终止符在., ^, 和$的行为中被识别。UNIX 行模式也可以通过嵌入式标志表达式(?d)启用。

在以下步骤中,我们将修改测试工具RegexTestHarness.java以创建一个具有大小写不敏感匹配的模式。

首先,修改代码以调用compile的另一个版本:

代码语言:javascript复制
Pattern pattern = 
Pattern.compile(console.readLine("%nEnter your regex: "),
Pattern.CASE_INSENSITIVE);

然后编译并运行测试工具以获得以下结果:

代码语言:javascript复制
Enter your regex: dog
Enter input string to search: DoGDOg
I found the text "DoG" starting at index 0 and ending at index 3.
I found the text "DOg" starting at index 3 and ending at index 6.

正如你所看到的,字符串字面量"dog"匹配两个实例,不考虑大小写。要编译带有多个标志的模式,请使用按位 OR 运算符"|"分隔要包含的标志。为了清晰起见,以下代码示例硬编码正则表达式而不是从Console中读取:

代码语言:javascript复制
pattern = Pattern.compile("[az]$", Pattern.MULTILINE | Pattern.UNIX_LINES);

你也可以指定一个int变量:

代码语言:javascript复制
final int flags = Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE;
Pattern pattern = Pattern.compile("aa", flags);

嵌入式标志表达式

也可以使用嵌入式标志表达式来启用各种标志。嵌入式标志表达式是compile的两参数版本的替代方案,并在正则表达式本身中指定。以下示例使用原始测试工具RegexTestHarness.java与嵌入式标志表达式(?i)来启用大小写不敏感匹配。

代码语言:javascript复制
Enter your regex: (?i)foo
Enter input string to search: FOOfooFoOfoO
I found the text "FOO" starting at index 0 and ending at index 3.
I found the text "foo" starting at index 3 and ending at index 6.
I found the text "FoO" starting at index 6 and ending at index 9.
I found the text "foO" starting at index 9 and ending at index 12.

再次,不管大小写,所有匹配都成功。

对应于Pattern的公共可访问字段的嵌入式标志表达式如下表所示:

常量

等效的嵌入式标志表达式

Pattern.CANON_EQ

Pattern.CASE_INSENSITIVE

(?i)

Pattern.COMMENTS

(?x)

Pattern.MULTILINE

(?m)

Pattern.DOTALL

(?s)

Pattern.LITERAL

Pattern.UNICODE_CASE

(?u)

Pattern.UNIX_LINES

(?d)

使用matches(String,CharSequence)方法

Pattern类定义了一个方便的matches方法,允许您快速检查给定输入字符串中是否存在模式。与所有公共静态方法一样,您应该通过其类名调用matches,例如Pattern.matches("\d","1");。在这个例子中,该方法返回true,因为数字"1"与正则表达式d匹配。

使用split(String)方法

split方法是一个很好的工具,用于收集与已匹配模式两侧的文本。如下所示,在SplitDemo.java中,split方法可以从字符串"one:two:three:four:five"中提取单词"one two three four five":

代码语言:javascript复制
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class SplitDemo {

    private static final String REGEX = ":";
    private static final String INPUT =
        "one:two:three:four:five";

    public static void main(String[] args) {
        Pattern p = Pattern.compile(REGEX);
        String[] items = p.split(INPUT);
        for(String s : items) {
            System.out.println(s);
        }
    }
}
代码语言:javascript复制
OUTPUT:

one
two
three
four
five

为简单起见,我们匹配了一个字符串字面量,即冒号(:),而不是一个复杂的正则表达式。由于我们仍在使用PatternMatcher对象,您可以使用 split 来获取任何正则表达式两侧的文本。这里是相同的示例,SplitDemo2.java,修改为按数字拆分:

代码语言:javascript复制
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class SplitDemo2 {

    private static final String REGEX = "\d";
    private static final String INPUT =
        "one9two4three7four1five";

    public static void main(String[] args) {
        Pattern p = Pattern.compile(REGEX);
        String[] items = p.split(INPUT);
        for(String s : items) {
            System.out.println(s);
        }
    }
}
代码语言:javascript复制
OUTPUT:

one
two
three
four
five

其他实用方法

您可能也会发现以下方法有些用处:

  • public static String quote(String s) 为指定的String返回一个字面模式String。此方法生成一个String,可用于创建一个Pattern,该Pattern将匹配String s,就好像它是一个字面模式。输入序列中的元字符或转义序列将不被赋予特殊含义。
  • public String toString() 返回此模式的String表示。这是编译此模式的正则表达式。

java.lang.String中的Pattern方法等效项

通过几种模仿java.util.regex.Pattern行为的方法,java.lang.String中也存在正则表达式支持。为方便起见,以下是它们 API 中的关键摘录。

  • public boolean matches(String regex): 告诉这个字符串是否与给定的正则表达式匹配。形式为*str*.matches(*regex*)的此方法的调用产生与表达式Pattern.matches(*regex*, *str*)完全相同的结果。
  • public String[] split(String regex, int limit): 将此字符串围绕给定正则表达式的匹配项拆分。形式为*str*.split(*regex*, *n*)的此方法的调用产生与表达式Pattern.compile(*regex*).split(*str*, *n*)相同的结果。
  • public String[] split(String regex): 将此字符串围绕给定正则表达式的匹配项拆分。此方法的工作方式与使用给定表达式和限制参数为零调用两参数拆分方法相同。结果数组中不包括尾随空字符串。

还有一个替换方法,用另一个CharSequence替换一个:

  • public String replace(CharSequence target,CharSequence replacement): 用指定的文字替换序列替换此字符串的每个与字面目标序列匹配的子字符串。替换从字符串的开头到结尾进行,例如,在字符串“aaa”中用“b”替换“aa”将导致“ba”而不是“ab”。

Matcher 类的方法

原文:docs.oracle.com/javase/tutorial/essential/regex/matcher.html

本节描述了Matcher类的一些额外有用的方法。为方便起见,下面列出的方法根据功能进行了分组。

索引方法

索引方法提供了有用的索引值,精确显示匹配在输入字符串中的位置:

  • public int start(): 返回先前匹配的起始索引。
  • public int start(int group): 返回在先前匹配操作期间由给定组捕获的子序列的起始索引。
  • public int end(): 返回匹配的最后一个字符后的偏移量。
  • public int end(int group): 返回在先前匹配操作期间由给定组捕获的子序列的最后一个字符后的偏移量。

学习方法

学习方法审查输入字符串并返回一个布尔值,指示模式是否被找到。

  • public boolean lookingAt(): 尝试从区域的开头开始匹配输入序列与模式。
  • public boolean find(): 尝试查找与模式匹配的输入序列的下一个子序列。
  • public boolean find(int start): 重置此匹配器,然后尝试查找从指定索引开始的输入序列的下一个与模式匹配的子序列。
  • public boolean matches(): 尝试将整个区域与模式匹配。

替换方法

替换方法是用于替换输入字符串中文本的有用方法。

  • public Matcher appendReplacement(StringBuffer sb, String replacement): 实现了一个非终端追加和替换步骤。
  • public StringBuffer appendTail(StringBuffer sb): 实现了一个终端追加和替换步骤。
  • public String replaceAll(String replacement):用给定替换字符串替换与模式匹配的输入序列的每个子序列。
  • public String replaceFirst(String replacement):用给定的替换字符串替换与模式匹配的输入序列的第一个子序列。
  • public static String quoteReplacement(String s):为指定的String返回一个字面替换String。此方法生成一个将作为Matcher类的appendReplacement方法中的字面替换sString。生成的String将匹配将s视为字面序列处理的字符序列。反斜杠('')和美元符号('$')将不被赋予特殊含义。

使用 startend 方法

这里有一个例子,MatcherDemo.java,它计算输入字符串中单词"dog"出现的次数。

代码语言:javascript复制
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class MatcherDemo {

    private static final String REGEX =
        "\bdog\b";
    private static final String INPUT =
        "dog dog dog doggie dogg";

    public static void main(String[] args) {
       Pattern p = Pattern.compile(REGEX);
       //  get a matcher object
       Matcher m = p.matcher(INPUT);
       int count = 0;
       while(m.find()) {
           count  ;
           System.out.println("Match number "
                                count);
           System.out.println("start(): "
                                m.start());
           System.out.println("end(): "
                                m.end());
      }
   }
}
代码语言:javascript复制
OUTPUT:

Match number 1
start(): 0
end(): 3
Match number 2
start(): 4
end(): 7
Match number 3
start(): 8
end(): 11

您可以看到,此示例使用单词边界来确保字母"d" "o" "g"不仅仅是更长单词的子字符串。它还提供了有关匹配发生在输入字符串的哪个位置的一些有用信息。start 方法返回在先前匹配操作期间由给定组捕获的子序列的起始索引,而 end 返回匹配的最后一个字符的索引加一。

使用 matcheslookingAt 方法

matcheslookingAt 方法都尝试将输入序列与模式进行匹配。然而,不同之处在于 matches 要求整个输入序列匹配,而 lookingAt 则不需要。这两种方法始终从输入字符串的开头开始。以下是完整代码,MatchesLooking.java

代码语言:javascript复制
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class MatchesLooking {

    private static final String REGEX = "foo";
    private static final String INPUT =
        "fooooooooooooooooo";
    private static Pattern pattern;
    private static Matcher matcher;

    public static void main(String[] args) {

        // Initialize
        pattern = Pattern.compile(REGEX);
        matcher = pattern.matcher(INPUT);

        System.out.println("Current REGEX is: "
                             REGEX);
        System.out.println("Current INPUT is: "
                             INPUT);

        System.out.println("lookingAt(): "
              matcher.lookingAt());
        System.out.println("matches(): "
              matcher.matches());
    }
}
代码语言:javascript复制
Current REGEX is: foo
Current INPUT is: fooooooooooooooooo
lookingAt(): true
matches(): false

使用 replaceFirst(String)replaceAll(String)

replaceFirstreplaceAll 方法替换与给定正则表达式匹配的文本。正如它们的名称所示,replaceFirst 替换第一次出现,而 replaceAll 替换所有出现。以下是 ReplaceDemo.java 代码:

代码语言:javascript复制
import java.util.regex.Pattern; 
import java.util.regex.Matcher;

public class ReplaceDemo {

    private static String REGEX = "dog";
    private static String INPUT =
        "The dog says meow. All dogs say meow.";
    private static String REPLACE = "cat";

    public static void main(String[] args) {
        Pattern p = Pattern.compile(REGEX);
        // get a matcher object
        Matcher m = p.matcher(INPUT);
        INPUT = m.replaceAll(REPLACE);
        System.out.println(INPUT);
    }
}
代码语言:javascript复制
OUTPUT: The cat says meow. All cats say meow.

在这个第一个版本中,所有 dog 的出现都被替换为 cat。但为什么要停在这里呢?与其仅替换简单的文字dog,不如替换与任何正则表达式匹配的文本。该方法的 API 表明,“给定正则表达式a*b,输入aabfooaabfooabfoob,替换字符串为-,对该表达式的匹配器调用此方法将产生字符串-foo-foo-foo-。”

以下是 ReplaceDemo2.java 代码:

代码语言:javascript复制
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class ReplaceDemo2 {

    private static String REGEX = "a*b";
    private static String INPUT =
        "aabfooaabfooabfoob";
    private static String REPLACE = "-";

    public static void main(String[] args) {
        Pattern p = Pattern.compile(REGEX);
        // get a matcher object
        Matcher m = p.matcher(INPUT);
        INPUT = m.replaceAll(REPLACE);
        System.out.println(INPUT);
    }
}
代码语言:javascript复制
OUTPUT: -foo-foo-foo-

要仅替换模式的第一次出现,只需调用 replaceFirst 而不是 replaceAll。它接受相同的参数。

使用 appendReplacement(StringBuffer,String)appendTail(StringBuffer)

Matcher 类还提供了 appendReplacementappendTail 方法用于文本替换。下面的示例,RegexDemo.java ,使用这两种方法实现与 replaceAll 相同的效果。

代码语言:javascript复制
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class RegexDemo {

    private static String REGEX = "a*b";
    private static String INPUT = "aabfooaabfooabfoob";
    private static String REPLACE = "-";

    public static void main(String[] args) {
        Pattern p = Pattern.compile(REGEX);
        Matcher m = p.matcher(INPUT); // get a matcher object
        StringBuffer sb = new StringBuffer();
        while(m.find()){
            m.appendReplacement(sb,REPLACE);
        }
        m.appendTail(sb);
        System.out.println(sb.toString());
    }
}
代码语言:javascript复制
OUTPUT: -foo-foo-foo- 

java.lang.String 中的 Matcher 方法等效

为方便起见,String 类也模仿了一些 Matcher 方法:

  • public String replaceFirst(String regex, String replacement):用给定的替换内容替换此字符串匹配给定正则表达式的第一个子字符串。形式为 *str*.replaceFirst(*regex*, *repl*) 的此方法调用产生的结果与表达式 Pattern.compile(*regex*).matcher(*str*).replaceFirst(*repl*) 完全相同。
  • public String replaceAll(String regex, String replacement):用给定的替换内容替换此字符串中与给定正则表达式匹配的每个子字符串。形式为 *str*.replaceAll(*regex*, *repl*) 的此方法调用产生的结果与表达式 Pattern.compile(*regex*).matcher(*str*).replaceAll(*repl*) 完全相同。

PatternSyntaxException 类的方法

原文:docs.oracle.com/javase/tutorial/essential/regex/pse.html

PatternSyntaxException是一个未经检查的异常,表示正则表达式模式中的语法错误。PatternSyntaxException类提供以下方法,帮助您确定出了什么问题:

  • public String getDescription(): 检索错误的描述。
  • public int getIndex(): 检索错误索引。
  • public String getPattern(): 检索错误的正则表达式模式。
  • public String getMessage(): 返回一个包含语法错误描述、错误索引、错误的正则表达式模式以及模式中错误索引的可视指示的多行字符串。

以下源代码,RegexTestHarness2.java,更新了我们的测试工具以检查格式不正确的正则表达式:

代码语言:javascript复制
import java.io.Console;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.regex.PatternSyntaxException;

public class RegexTestHarness2 {

    public static void main(String[] args){
        Pattern pattern = null;
        Matcher matcher = null;

        Console console = System.console();
        if (console == null) {
            System.err.println("No console.");
            System.exit(1);
        }
        while (true) {
            try{
                pattern = 
                Pattern.compile(console.readLine("%nEnter your regex: "));

                matcher = 
                pattern.matcher(console.readLine("Enter input string to search: "));
            }
            catch(PatternSyntaxException pse){
                console.format("There is a problem"  
                               " with the regular expression!%n");
                console.format("The pattern in question is: %s%n",
                               pse.getPattern());
                console.format("The description is: %s%n",
                               pse.getDescription());
                console.format("The message is: %s%n",
                               pse.getMessage());
                console.format("The index is: %s%n",
                               pse.getIndex());
                System.exit(0);
            }
            boolean found = false;
            while (matcher.find()) {
                console.format("I found the text"  
                    " "%s" starting at "  
                    "index %d and ending at index %d.%n",
                    matcher.group(),
                    matcher.start(),
                    matcher.end());
                found = true;
            }
            if(!found){
                console.format("No match found.%n");
            }
        }
    }
}

要运行此测试,请将?i)foo输入为正则表达式。这个错误是程序员在嵌入式标志表达式(?i)中忘记开括号的常见情况。这样做将产生以下结果:

代码语言:javascript复制
Enter your regex: ?i)
There is a problem with the regular expression!
The pattern in question is: ?i)
The description is: Dangling meta character '?'
The message is: Dangling meta character '?' near index 0
?i)
^
The index is: 0

从这个输出中,我们可以看到语法错误是在索引 0 处的悬空元字符(问号)。缺少的开括号是罪魁祸首。

Unicode 支持

原文:docs.oracle.com/javase/tutorial/essential/regex/unicode.html

从 JDK 7 版本开始,正则表达式模式匹配已扩展功能以支持 Unicode 6.0。

  • 匹配特定代码点
  • Unicode 字符属性

匹配特定代码点

您可以使用形式为uFFFF的转义序列匹配特定的 Unicode 代码点,其中FFFF是您想匹配的代码点的十六进制值。例如,u6771匹配东方的汉字。

或者,您可以使用 Perl 风格的十六进制表示法指定一个代码点,x{...}。例如:

代码语言:javascript复制
String hexPattern = "x{"   Integer.toHexString(codePoint)   "}";

Unicode 字符属性

每个 Unicode 字符除了其值之外,还具有某些属性或特性。您可以使用表达式p{*prop*}匹配属于特定类别的单个字符。您可以使用表达式P{*prop*}匹配属于特定类别的单个字符。

支持的属性类型有脚本、区块和“通用”类别。

脚本

要确定代码点是否属于特定脚本,您可以使用script关键字或sc的简写形式,例如,p{script=Hiragana}。或者,您可以在脚本名称前加上字符串Is,例如p{IsHiragana}

Pattern支持的有效脚本名称是UnicodeScript.forName接受的那些。

区块

可以使用block关键字或blk的简写形式指定一个区块,例如,p{block=Mongolian}。或者,您可以在区块名称前加上字符串In,例如p{InMongolian}

Pattern支持的有效区块名称是UnicodeBlock.forName接受的那些。

通用类别

类别可以用可选前缀Is指定。例如,IsL匹配 Unicode 字母的类别。类别也可以通过使用general_category关键字或简写形式gc来指定。例如,大写字母可以使用general_category=Lugc=Lu来匹配。

支持的类别是由Character类指定的Unicode 标准版本中的类别。

其他资源

原文:docs.oracle.com/javase/tutorial/essential/regex/resources.html

现在您已经完成了关于正则表达式的这节课,您可能会发现您的主要参考资料将是以下类的 API 文档:PatternMatcherPatternSyntaxException

对于正则表达式构造的行为更精确的描述,我们建议阅读 Jeffrey E. F. Friedl 的书籍精通正则表达式

问题和练习:正则表达式

原文:docs.oracle.com/javase/tutorial/essential/regex/QandE/questions.html

问题

  1. java.util.regex包中有哪三个公共类?描述每个类的目的。
  2. 考虑字符串字面值"foo"。起始索引是多少?结束索引是多少?解释这些数字的含义。
  3. 普通字符和元字符之间有什么区别?举例说明。
  4. 如何让一个元字符表现得像一个普通字符?
  5. 一组字符被方括号括起来叫什么?它的作用是什么?
  6. 这里有三个预定义的字符类:dsw。描述每一个,并使用方括号重写它们。
  7. 对于每个dsw,写出两个简单的表达式,匹配相反的字符集。
  8. 考虑正则表达式(dog){3}。识别两个子表达式。这个表达式匹配什么字符串?

练习

  1. 使用反向引用编写一个表达式,只有当一个人的名字和姓氏相同时才匹配该人的名字。

检查你的答案。

路径:部署

原文:docs.oracle.com/javase/tutorial/deployment/index.html

Java 富互联网应用程序(RIA)是具有类似桌面应用程序特征的应用程序,但是通过互联网部署。Java RIA 可以作为 Java 小程序或 Java Web Start 应用程序开发和部署。

  • 小程序 - Java 小程序在浏览器环境中运行。Java 插件软件控制 Java 小程序的执行和生命周期。
  • Java Web Start 应用程序 - Java Web Start 应用程序首次通过浏览器启动。随后可以通过桌面快捷方式启动。一旦下载了 Java Web Start 应用程序并且用户接受了其安全证书,它的行为几乎像一个独立的应用程序。

基于组件的架构用于富互联网应用程序

在过去,决定将 Java 富互联网应用程序作为小程序在浏览器内部部署,还是作为 Java Web Start 应用程序在浏览器外部部署,可能会显著影响应用程序的设计。有了最新的 Java 插件,这个决定变得简单多了。

传统上,应用程序在 main 方法中构建其用户界面,包括顶级 Frame。这种编程风格阻碍了应用程序在浏览器中的重新部署,因为它假定应用程序创建自己的 Frame。在浏览器中作为小程序运行时,小程序是应该容纳应用程序用户界面的顶级容器。不需要顶级 Frame

在设计 Java 富互联网应用程序时,请使用基于组件的架构。尝试将其功能组织成一个或多个可以组合在一起的组件。在这种情况下,“组件”一词指的是 AWT Component 类的子类、Swing JComponent 类或另一个子类的 GUI 元素。例如,您可以有一个顶级 JPanel,其中包含其他 UI 组件(如更多嵌套的 JPanels 和文本字段、组合框等)。通过这种设计,将核心功能部署为小程序或 Java Web Start 应用程序变得相对容易。

要部署为 Java 小程序,只需将核心功能封装在 AppletJApplet 中,并添加必要的浏览器特定功能。要部署为 Java Web Start 应用程序,请将功能封装在 JFrame 中。

选择 Java 小程序和 Java Web Start 应用程序之间

富互联网应用程序决策指南包含详细信息,帮助您决定将代码部署为 Java 小程序还是 Java Web Start 应用程序。

自包含应用程序替代方案

自包含应用程序提供了一种部署选项,不需要浏览器。用户在本地安装您的应用程序,并类似于本机应用程序运行它。自包含应用程序包括运行应用程序所需的 JRE,因此用户始终拥有正确的 JRE。

本教程讨论了 RIA 和自包含应用程序的开发和部署。请查看新功能,了解客户端 Java 运行时环境(JRE)软件各个版本引入的功能。

支持工具

课程:Java 小程序

原文:docs.oracle.com/javase/tutorial/deployment/applet/index.html

本课程讨论了 Java 小程序的基础知识,如何开发与环境交互丰富的小程序,以及如何部署小程序。

Java 小程序是一种特殊类型的 Java 程序,可以由启用了 Java 技术的浏览器从互联网上下载并运行。小程序通常嵌入在网页中,并在浏览器的上下文中运行。小程序必须是 java.applet.Applet 类的子类。Applet 类提供了小程序与浏览器环境之间的标准接口。

Swing 提供了 Applet 类的一个特殊子类,名为 javax.swing.JApplet。应该使用 JApplet 类来构建使用 Swing 组件构建其图形用户界面(GUI)的所有小程序。

浏览器的 Java 插件软件管理小程序的生命周期。

使用 Web 服务器来测试本课程中的示例。不建议使用本地小程序,当 Java 控制面板中的安全级别设置为高或非常高时,本地小程序将被阻止。


注意: 要运行小程序,请在 Microsoft Edge 上使用 IE 模式。请参阅Microsoft Edge Internet Explorer mode: Getting Started guide。



注意: 请确保您的客户端机器上至少安装了Java SE Development Kit (JDK) 6 update 10版本,然后再继续。您将需要此版本才能查看示例丰富的互联网应用程序并在不中断的情况下阅读后续章节。


开始使用小程序

原文:docs.oracle.com/javase/tutorial/deployment/applet/getStarted.html

接下来展示的 HelloWorld 小程序是一个显示字符串"Hello World"的 Java 类。

//<![CDATA[ var attributes = { code:‘HelloWorld.class’, archive:‘examples/dist/applet_HelloWorld/applet_HelloWorld.jar’, width:150, height:30} ; var parameters = { permissions:‘sandbox’ } ; deployJava.runApplet(attributes, parameters, ‘1.4’); //]]>


注意: 如果你看不到示例运行,可能需要在浏览器中启用 JavaScript 解释器,以便部署工具包脚本能够正常运行。


以下是 HelloWorld 小程序的源代码:

代码语言:javascript复制
import javax.swing.JApplet;
import javax.swing.SwingUtilities;
import javax.swing.JLabel;

public class HelloWorld extends JApplet {
    //Called when this applet is loaded into the browser.
    public void init() {
        //Execute a job on the event-dispatching thread; creating this applet's GUI.
        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                public void run() {
                    JLabel lbl = new JLabel("Hello World");
                    add(lbl);
                }
            });
        } catch (Exception e) {
            System.err.println("createGUI didn't complete successfully");
        }
    }
}

这样的小程序通常由浏览器中的Java 插件软件管理和运行。

下载源代码以进一步进行实验。

定义一个小程序子类

原文:docs.oracle.com/javase/tutorial/deployment/applet/subclass.html

每个 Java 小程序都必须定义AppletJApplet类的子类。在 Hello World 小程序中,这个子类被称为HelloWorld。以下是HelloWorld类的源代码。

代码语言:javascript复制
import javax.swing.JApplet;
import javax.swing.SwingUtilities;
import javax.swing.JLabel;

public class HelloWorld extends JApplet {
    //Called when this applet is loaded into the browser.
    public void init() {
        //Execute a job on the event-dispatching thread; creating this applet's GUI.
        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                public void run() {
                    JLabel lbl = new JLabel("Hello World");
                    add(lbl);
                }
            });
        } catch (Exception e) {
            System.err.println("createGUI didn't complete successfully");
        }
    }
}

Java applets inherit significant functionality from the Applet or JApplet class, including the capabilities to communicate with the browser and present a graphical user interface (GUI) to the user.

一个将使用来自 Swing(Java 的 GUI 工具包)的 GUI 组件的小程序应该扩展javax.swing.JApplet基类,它提供了与 Swing 的 GUI 设施最佳集成。

JApplet提供了一个根窗格,它与 Swing 的JFrameJDialog组件具有相同的顶层组件结构,而Applet只提供了一个基本面板。有关如何使用此功能的更多详细信息,请参见如何使用根窗格。

一个小程序可以扩展java.applet.Applet类,当它不使用 Swing 的 GUI 组件时。

里程碑方法

原文:docs.oracle.com/javase/tutorial/deployment/applet/appletMethods.html

Applet类为小程序执行提供了一个框架,定义了系统在里程碑发生时调用的方法。里程碑是小程序生命周期中的重要事件。大多数小程序会覆盖其中一些或全部方法以适当地响应里程碑。

init 方法

init方法适用于不需要太长时间的一次性初始化。init方法通常包含通常放在构造函数中的代码。小程序通常没有构造函数的原因是在调用其init方法之前不能保证其具有完整的环境。保持init方法简短,以便您的小程序可以快速加载。

start 方法

每个在初始化后执行任务(除了直接响应用户操作)的小程序必须覆盖start方法。start方法启动小程序的执行。从start方法快速返回是一个良好的实践。如果需要执行计算密集型操作,最好为此目的启动一个新线程。

stop 方法

大多数覆盖start方法的小程序也应该覆盖stop方法。stop方法应该暂停小程序的执行,这样当用户不查看小程序页面时,它就不会占用系统资源。例如,显示动画的小程序在用户不查看时应该停止尝试绘制动画。

destroy 方法

许多小程序不需要覆盖destroy方法,因为它们的stop方法(在destroy之前调用)将执行关闭小程序执行所需的所有任务。但是,destroy方法适用于需要释放额外资源的小程序。


注意: 尽量保持destroy方法的实现尽可能简短,因为不能保证该方法会完全执行。在长destroy方法完成之前,Java 虚拟机可能会退出。


小程序的生命周期

原文:docs.oracle.com/javase/tutorial/deployment/applet/lifeCycle.html

小程序可以对以下重大事件做出反应:

  • 它可以初始化自身。
  • 它可以开始运行。
  • 它可以停止运行。
  • 它可以执行最终清理,为即将卸载做准备。

本节介绍了一个新的小程序Simple,它使用了所有这些方法。与 Java 应用程序不同,小程序不需要实现main方法。

这是Simple小程序。

//<![CDATA[ var attributes = { code:‘Simple.class’, archive:‘examples/dist/applet_Simple/applet_Simple.jar’, width:500, height:20} ; var parameters = { permissions:‘sandbox’ } ; deployJava.runApplet(attributes, parameters, ‘1.4’); //]]>


注意: 如果您看不到示例运行,请确保在浏览器中启用 JavaScript 解释器,以便部署工具包脚本能够正常运行。


以下是Simple小程序的源代码。该小程序在其生命周期中遇到重要里程碑时会显示描述性字符串,例如当用户首次访问包含小程序的页面时。

代码语言:javascript复制
import java.applet.Applet;
import java.awt.Graphics;

//No need to extend JApplet, since we don't add any components;
//we just paint.
public class Simple extends Applet {

    StringBuffer buffer;

    public void init() {
        buffer = new StringBuffer();
        addItem("initializing... ");
    }

    public void start() {
        addItem("starting... ");
    }

    public void stop() {
        addItem("stopping... ");
    }

    public void destroy() {
        addItem("preparing for unloading...");
    }

    private void addItem(String newWord) {
        System.out.println(newWord);
        buffer.append(newWord);
        repaint();
    }

    public void paint(Graphics g) {
	//Draw a Rectangle around the applet's display area.
        g.drawRect(0, 0, 
		   getWidth() - 1,
		   getHeight() - 1);

	//Draw the current string inside the rectangle.
        g.drawString(buffer.toString(), 5, 15);
    }
}

注意: 在此示例中,Applet 类被扩展,而不是 Swing JApplet 类,因为 Swing 组件不需要添加到此小程序中。


加载小程序

由于小程序被加载,您应该看到文本“初始化…启动…”。小程序加载时,会发生以下情况:

  • 创建小程序控制类的一个实例(Applet子类)。
  • 小程序初始化自身。
  • 小程序开始运行。

离开并返回到小程序的页面

当用户离开页面,例如前往另一页时,浏览器会停止并销毁小程序。小程序的状态不会被保留。当用户返回页面时,浏览器会初始化并启动小程序的新实例。

重新加载小程序

当您刷新或重新加载浏览器页面时,当前小程序实例会被停止和销毁,并创建一个新实例。

退出浏览器

当用户退出浏览器时,小程序有机会在浏览器退出之前停止自身并执行最终清理。

下载源代码以进一步实验Simple 小程序示例。

Applet 的执行环境

原文:docs.oracle.com/javase/tutorial/deployment/applet/appletExecutionEnv.html

Java applet 在浏览器的上下文中运行。浏览器中的 Java 插件软件控制 Java applet 的启动和执行。浏览器还有一个 JavaScript 解释器,用于运行网页上的 JavaScript 代码。本主题描述了 Java 平台标准版 6 更新 10 中发布的 Java 插件软件的行为。

Java 插件

Java 插件软件为每个 Java applet 创建一个工作线程。它在 Java Runtime Environment (JRE)软件的一个实例中启动 applet。通常,所有 applet 在同一个 JRE 实例中运行。Java 插件软件在以下情况下启动新的 JRE 实例:

  • 当 applet 请求在特定版本的 JRE 中执行时。
  • 当 applet 指定自己的 JRE 启动参数时,例如堆大小。如果新 applet 的要求是现有 JRE 的子集,则新 applet 使用现有 JRE,否则启动新的 JRE 实例。

如果满足以下条件,applet 将在现有 JRE 中运行:

  • applet 所需的 JRE 版本与现有的 JRE 匹配。
  • JRE 的启动参数满足 applet 的要求。

以下图表显示了 applet 在 JRE 中的执行方式。

这是 Java 插件在不同 JRE 版本上运行 applet 的图片。这是 Java 插件在不同 JRE 版本上运行 applet 的图片。

Java 插件和 JavaScript 解释器的交互

Java applet 可以调用网页中存在的 JavaScript 函数。JavaScript 函数也允许调用同一网页上嵌入的 applet 的方法。Java 插件软件和 JavaScript 解释器协调 Java 代码到 JavaScript 代码的调用以及 JavaScript 代码到 Java 代码的调用。

Java 插件软件是多线程的,而 JavaScript 解释器在单个线程上运行。因此,为了避免线程相关问题,特别是当多个 applet 同时运行时,请保持 Java 代码和 JavaScript 代码之间的调用简短,并尽量避免往返。查看以下主题以了解 Java 代码和 JavaScript 代码之间的交互更多信息:

  • 从 Applet 调用 JavaScript 代码
  • 从 JavaScript 代码调用 Applet 方法

开发 Applet

原文:docs.oracle.com/javase/tutorial/deployment/applet/developingApplet.html

使用基于组件的架构设计的应用程序可以开发为 Java applet。考虑具有基于 Swing 的图形用户界面(GUI)的 Java applet 的示例。通过组件化设计,GUI 可以使用更小的构建块或组件构建。以下是用于创建 applet GUI 的一般步骤:

  • 创建一个名为MyTopJPanel的类,它是javax.swing.JPanel的子类。在MyTopJPanel类的构造函数中布置您的 applet 的 GUI 组件。
  • 创建一个名为MyApplet的类,它是javax.swing.JApplet的子类。
  • MyAppletinit方法中,实例化MyTopJPanel并将其设置为 applet 的内容窗格。

以下部分通过使用动态树演示 applet 更详细地探讨这些步骤。如果您对 Swing 不熟悉,请参阅使用 Swing 创建 GUI 以了解更多关于使用 Swing GUI 组件的信息。

//<![CDATA[ var attributes = { code:‘appletComponentArch.DynamicTreeApplet.class’, archive:‘examples/dist/applet_ComponentArch_DynamicTreeDemo/DynamicTreeDemo.jar’, width:300, height:300} ; var parameters = {jnlp_href: ‘examples/dist/applet_ComponentArch_DynamicTreeDemo/dynamictree_applet.jnlp’} ; deployJava.runApplet(attributes, parameters, ‘1.4’); //]]>


注意: 如果您看不到示例运行,请确保在浏览器中启用 JavaScript 解释器,以便部署工具包脚本能够正常运行。


创建顶部JPanel

创建一个是JPanel子类的类。这个顶部JPanel充当所有其他 UI 组件的容器。在下面的示例中,DynamicTreePanel类是最顶层的JPanelDynamicTreePanel类的构造函数调用其他方法来正确创建和布局 UI 控件。

代码语言:javascript复制
public class DynamicTreePanel extends JPanel implements ActionListener {
    private int newNodeSuffix = 1;
    private static String ADD_COMMAND = "add";
    private static String REMOVE_COMMAND = "remove";
    private static String CLEAR_COMMAND = "clear";

    private DynamicTree treePanel;

    public DynamicTreePanel() {
        super(new BorderLayout());

        //Create the components.
        treePanel = new DynamicTree();
        populateTree(treePanel);

        JButton addButton = new JButton("Add");
        addButton.setActionCommand(ADD_COMMAND);
        addButton.addActionListener(this);

        JButton removeButton = new JButton("Remove");

        // ...

        JButton clearButton = new JButton("Clear");

        // ...

        //Lay everything out.
        treePanel.setPreferredSize(
            new Dimension(300, 150));
        add(treePanel, BorderLayout.CENTER);

        JPanel panel = new JPanel(new GridLayout(0,3));
        panel.add(addButton);
        panel.add(removeButton); 
        panel.add(clearButton);
        add(panel, BorderLayout.SOUTH);
    }
    // ...
}

创建 Applet

对于具有基于 Swing 的 GUI 的 Java applet,请创建一个类,它是javax.swing.JApplet的子类。不包含基于 Swing 的 GUI 的 applet 可以扩展java.applet.Applet类。

覆盖 applet 的init方法以实例化您的顶部JPanel类并创建 applet 的 GUI。DynamicTreeApplet类的init方法在 AWT 事件分发线程中调用createGUI方法。

代码语言:javascript复制
package appletComponentArch;

import javax.swing.JApplet;
import javax.swing.SwingUtilities;

public class DynamicTreeApplet extends JApplet {
    //Called when this applet is loaded into the browser.
    public void init() {
        //Execute a job on the event-dispatching thread; creating this applet's GUI.
        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                public void run() {
                    createGUI();
                }
            });
        } catch (Exception e) { 
            System.err.println("createGUI didn't complete successfully");
        }
    }

    private void createGUI() {
        //Create and set up the content pane.
        DynamicTreePanel newContentPane = new DynamicTreePanel();
        newContentPane.setOpaque(true); 
        setContentPane(newContentPane);        
    }        
}

将核心功能与最终部署机制分离的好处

另一种创建 applet 的方法是只需移除抽象层(单独的顶部JPanel)并在 applet 的init方法中布置所有控件。直接在 applet 中创建 GUI 的缺点是,如果以后选择将功能部署为 Java Web Start 应用程序,则现在将更难部署您的功能。

在动态树演示示例中,核心功能位于DynamicTreePanel类中。现在,将DynamicTreePanel类放入JFrame并部署为 Java Web Start 应用程序变得轻而易举。

因此,为了保持可移植性并保持部署选项开放,请按照本页描述的基于组件的设计。

下载源代码以进一步实验动态树演示程序示例。

部署一个 Applet

译文:docs.oracle.com/javase/tutorial/deployment/applet/deployingApplet.html

要部署您的 Java applet,首先编译源代码,将其打包为 JAR 文件,并对 JAR 文件进行签名。

Java applet 可以以两种方式启动。

  • 您可以使用 Java 网络启动协议(JNLP)启动您的 applet。使用 JNLP 启动的 applet 可以访问强大的 JNLP API 和扩展。
  • 或者,您可以通过直接在 applet 标记中指定 applet 的启动属性来启动 applet。然而,这种部署 applet 的旧方法对 applet 施加了严格的安全限制。

部署工具包脚本包含可用于在网页中部署 applet 的有用 JavaScript 函数。

如果您对这些部署技术不熟悉,请在继续之前查看 深入部署 课程。

以下是一些逐步说明,用于打包和部署您的 applet。Dynamic Tree Demo applet 用于说明 applet 的部署。您可能希望设置构建脚本来执行以下一些步骤。

//<![CDATA[ var attributes = { code:‘appletComponentArch.DynamicTreeApplet.class’, archive:‘examples/dist/applet_ComponentArch_DynamicTreeDemo/DynamicTreeDemo.jar’, width:300, height:300} ; var parameters = {jnlp_href: ‘examples/dist/applet_ComponentArch_DynamicTreeDemo/dynamictree_applet.jnlp’} ; deployJava.runApplet(attributes, parameters, ‘1.7’); //]]>


注意: 如果您看不到示例运行,请确保在浏览器中启用 JavaScript 解释器,以便部署工具包脚本能够正常运行。


编译您的 applet 的 Java 代码,并确保所有类文件和资源(如图像)位于单独的目录中。

在 DynamicTree Demo applet 的情况下,编译后的类文件将放置在 build/classes/appletComponentArch 目录中。

创建一个包含您的 applet 需要的任何 JAR 文件清单属性的文本文件。

对于 DynamicTree Demo applet,创建一个名为 mymanifest.txt 的文件在 build/classes 目录中,并添加 PermissionsCodebaseApplication-Name 属性。该 applet 不需要访问用户系统资源,因此对于权限使用 sandbox。对于代码库,使用您将加载示例的域,例如 myserver.com。将以下属性添加到 mymanifest.txt 文件中。

代码语言:javascript复制
Permissions: sandbox
Codebase: myserver.com
Application-Name: Dynamic Tree Demo

其他清单属性可用于限制 applet 仅使用受信任的代码,并为需要在特权 Java 代码和沙箱 Java 代码之间进行调用,或者具有调用 applet 的 JavaScript 代码的 applet 提供安全性。请参阅 使用清单属性增强安全性 课程以了解更多可用的清单属性。

创建一个包含您 applet 的类文件和资源的 JAR 文件。在您之前创建的 mymanifest.txt 文件中包含清单属性。

例如,以下命令将创建一个 JAR 文件,其中包含 build/classes/appletComponentArch 目录中的类文件和 build/classes 目录中的清单文件。

代码语言:javascript复制
% cd build/classes
% jar cvfm DynamicTreeDemo.jar mymanifest.txt appletComponentArch

参阅 在 JAR 文件中打包程序 课程,了解有关创建和使用 JAR 文件的更多信息。

为您的 applet 签署 JAR 文件并为签名加上时间戳。使用由受信任的证书颁发机构颁发的有效的当前代码签名证书,向用户提供确保可以安全运行 applet 的保证。

请参阅 签署 JAR 文件 课程以获取更多信息。

如果您想要使用签名的 JNLP 文件以确保安全性,请按照下一步中描述的方式创建 JNLP 文件,并在签名 JAR 文件之前将其包含在 JAR 文件中。有关详细信息,请参阅 Java 平台标准版部署指南中的 签名的 JNLP 文件。

创建描述您的 applet 应如何启动的 JNLP 文件。

这是用于启动动态树演示 applet 的 JNLP 文件。

dynamictree_applet.jnlp 的源代码如下:

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0 " codebase="" href="">
    <information>
        <title>Dynamic Tree Demo</title>
        <vendor>Dynamic Team</vendor>
    </information>
    <resources>
        <!-- Application Resources -->
        <j2se version="1.7 "
            href="http://java.sun.com/products/autodl/j2se" />
        <jar href="DynamicTreeDemo.jar" main="true" />

    </resources>
    <applet-desc 
         name="Dynamic Tree Demo Applet"
         main-class="components.DynamicTreeApplet"
         width="300"
         height="300">
     </applet-desc>
     <update check="background"/>
</jnlp>                                   

请注意,JNLP 文件中不存在请求额外权限的安全元素,因此 applet 仅在安全沙箱中运行。

主题,JNLP 文件的结构,描述了 JNLP 文件的语法和选项。

创建将显示 applet 的 HTML 页面。调用部署工具包函数以部署 applet。

在我们的示例中,动态树演示 applet 部署在 AppletPage.html 中。

代码语言:javascript复制
<body>
    <!-- ... -->
    <script src="https://www.java.com/js/deployJava.js"></script>
    <script> 
        var attributes = {
            code:'components.DynamicTreeApplet',  width:300, height:300} ; 
        var parameters = {jnlp_href: 'dynamictree_applet.jnlp'} ; 
        deployJava.runApplet(attributes, parameters, '1.7'); 
    </script>
    <!-- ... -->
</body>

将 applet 的 JAR 文件、JNLP 文件和 HTML 页面放置在适当的文件夹中。

对于此示例,请将 DynamicTreeDemo.jardynamictree_applet.jnlpAppletPage.html 放置在本地计算机或 Web 服务器上的同一目录中。建议使用 Web 服务器。要从本地计算机运行,必须将应用程序添加到例外站点列表中,该列表可从 Java 控制面板的安全选项卡中管理。

在浏览器中打开 applet 的 HTML 页面以查看 applet。在提示时同意运行 applet。检查 Java 控制台日志以查看错误和调试消息。

下载源代码 以进一步尝试 动态树演示 applet 示例。

使用 Applet 标签部署

原文:docs.oracle.com/javase/tutorial/deployment/applet/html.html

如果您不确定最终用户的浏览器是否启用了 JavaScript 解释器,您可以通过手动编码 <applet> HTML 标签来部署您的 Java applet,而不是使用 Deployment Toolkit 函数。根据您需要支持的浏览器,您可能需要使用 <object><embed> HTML 标签来部署您的 Java applet。查看W3C HTML 规范以获取有关这些标签的使用详情。

您可以使用 Java 网络启动协议(JNLP)启动您的 applet,或者直接在 <applet> 标签中指定启动属性。

部署准备

按照部署 applet 主题中描述的步骤编译您的源代码,创建并签名 JAR 文件,如有必要创建 JNLP 文件。部署的整体步骤仍然相关。只有包含 applet 的 HTML 页面的内容会发生变化。

手动编码 Applet 标签,使用 JNLP 启动

AppletPage_WithAppletTag.html 页面使用手动编码的 <applet> 标签部署了 Dynamic Tree Demo applet(意味着该 applet 不是使用自动生成所需 HTML 的 Deployment Toolkit 部署的)。该 applet 仍然使用 JNLP 启动。JNLP 文件在 jnlp_href 属性中指定。

代码语言:javascript复制
<applet code = 'appletComponentArch.DynamicTreeApplet' 
        jnlp_href = 'dynamictree_applet.jnlp'
        width = 300
        height = 300 />

手动编码 Applet 标签,无需使用 JNLP 启动

使用 JNLP 是部署 applet 的首选方式,但您也可以在没有 JNLP 文件的情况下部署您的 applet。

AppletPage_WithAppletTagNoJNLP.html 部署了 Dynamic Tree Demo applet,如下面的代码片段所示。

代码语言:javascript复制
<applet code = 'appletComponentArch.DynamicTreeApplet' 
    archive = 'DynamicTreeDemo.jar'
    width = 300
    height = 300>
    <param name="permissions" value="sandbox" />
</applet>

其中

  • code 是 applet 类的名称。
  • archive 是包含 applet 及其资源的 jar 文件的名称。
  • width 是 applet 的宽度。
  • height 是 applet 的高度。
  • permissions 表示 applet 是否在安全沙箱中运行。将值指定为"sandbox"以在沙箱中运行。将值指定为"all-permissions"以在沙箱外运行。如果未提供 permissions 参数,则签名的 applet 默认为"all-permissions",未签名的 applet 默认为"sandbox"。

进一步使用小程序

原文:docs.oracle.com/javase/tutorial/deployment/applet/doingMoreWithApplets.html

Java 小程序 API 使您能够充分利用小程序与浏览器之间的密切关系。该 API 由javax.swing.JApplet类和java.applet.AppletContext接口提供。小程序执行架构使小程序能够与其环境交互,从而产生丰富的用户体验。小程序可以操纵其父网页,与网页中的 JavaScript 代码交互,查找在同一网页中运行的其他小程序等等。

探索 Java 小程序的高级功能在后续主题中。

有关常见小程序和 Java Web 启动应用程序的高级主题的进一步信息,请参阅使用 Java 丰富互联网应用程序做更多事情(例如设置参数和属性,使用 Java 网络启动协议 API)。

查找和加载数据文件

原文:docs.oracle.com/javase/tutorial/deployment/applet/data.html

每当 Java applet 需要从指定了相对 URL 的文件加载数据(指定了文件位置但不完全指定的 URL),applet 通常使用代码库或文档库来形成完整的 URL。

JAppletgetCodeBase 方法返回的代码库是一个 URL,指定了 applet 的类加载的目录。对于本地部署的 applet,getCodeBase 方法返回 null。

JAppletgetDocumentBase 方法返回的文档库指定包含 applet 的 HTML 页面的目录。对于本地部署的 applet,getDocumentBase 方法返回 null。

除非 <applet> 标签指定了代码库,否则代码库和文档库都指向同一服务器上的同一目录。

applet 可能需要的数据,或者需要依赖的备份数据,通常相对于代码库指定。通常由 applet 开发人员指定的数据,通常通过使用参数指定,通常相对于文档库指定。


**注意:**出于安全原因,浏览器限制了不受信任的 applet 可以读取的 URL。例如,大多数浏览器不允许不受信任的 applet 使用 “…” 访问代码库或文档库上面的目录。此外,由于不受信任的 applet 不能读取除了位于 applet 源主机上的文件之外的文件,因此如果文档和不受信任的 applet 位于不同的服务器上,则文档库通常是无用的。


JApplet 类定义了方便的图像加载和声音加载方法,使您能够相对于基本 URL 指定图像和声音。例如,假设 applet 设置为以下图中显示的其中一个目录结构。

显示图像文件和类文件位于不同位置的两个目录结构,具有不同的结构。显示图像文件和类文件位于不同位置的两个目录结构,具有不同的结构。

要创建一个使用 imgDir 下的 a.gif 图像文件的 Image 对象,applet 可以使用以下代码:

代码语言:javascript复制
Image image = getImage(getCodeBase(), "imgDir/a.gif");

定义和使用 Applet 参数

原文:docs.oracle.com/javase/tutorial/deployment/applet/param.html

参数对于 Java applet 就像命令行参数对于应用程序一样重要。它们使用户能够自定义 applet 的操作。通过定义参数,你可以增加 applet 的灵活性,使其在多种情况下工作而无需重新编码和重新编译。

指定 Applet 的输入参数

你可以在 applet 的 Java 网络启动协议(JNLP)文件或 <applet> 标签的 <parameter> 元素中指定 applet 的输入参数。通常最好在 applet 的 JNLP 文件中指定参数,这样即使 applet 部署在多个网页上,参数也可以一致提供。如果 applet 的参数会因网页而异,则应在 <applet> 标签的 <parameter> 元素中指定参数。

如果你对 JNLP 不熟悉,请查看 Java 网络启动协议 主题获取更多信息。

考虑一个需要三个参数的 applet。paramStrparamInt 参数在 applet 的 JNLP 文件中指定,applettakesparams.jnlp

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0 " codebase="" href="">
    <!-- ... -->
    <applet-desc
         name="Applet Takes Params"
         main-class="AppletTakesParams"
         width="800"
         height="50">
             <param name="paramStr"
                 value="someString"/>
             <param name="paramInt" value="22"/>
     </applet-desc>
     <!-- ... -->
</jnlp>

paramOutsideJNLPFile 参数在传递给部署工具包脚本的 runApplet 函数的 parameters 变量中指定在 AppletPage.html

代码语言:javascript复制
<html>
  <head>
    <title>Applet Takes Params</title>
    <meta http-equiv="Content-Type" content="text/html;
        charset=windows-1252">
  </head>
  <body>
    <h1>Applet Takes Params</h1>

    <script
      src="https://www.java.com/js/deployJava.js"></script>
    <script>
        var attributes = { code:'AppletTakesParams.class',
            archive:'applet_AppletWithParameters.jar',
            width:800, height:50 };
        var parameters = {jnlp_href: 'applettakesparams.jnlp',
            paramOutsideJNLPFile: 'fooOutsideJNLP' };
        deployJava.runApplet(attributes, parameters, '1.7');
    </script>

  </body>
</html>

查看 部署 Applet 获取有关 runApplet 函数的更多信息。

检索 Applet 的输入参数

你可以使用 Applet 类的 getParameter 方法来检索 applet 的输入参数。AppletTakesParams.java applet 检索并显示其所有输入参数(paramStrparamIntparamOutsideJNLPFile)。

代码语言:javascript复制
import javax.swing.JApplet;
import javax.swing.SwingUtilities;
import javax.swing.JLabel;

public class AppletTakesParams extends JApplet {
    public void init() {
        final String  inputStr = getParameter("paramStr");        
        final int inputInt = Integer.parseInt(getParameter("paramInt"));
        final String inputOutsideJNLPFile = getParameter("paramOutsideJNLPFile");

        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                public void run() {
                    createGUI(inputStr, inputInt, inputOutsideJNLPFile);
                }
            });
        } catch (Exception e) {
            System.err.println("createGUI didn't successfully complete");
        }
    }
    private void createGUI(String inputStr, int inputInt, String inputOutsideJNLPFile) {
        String text = "Applet's parameters are -- inputStr: "   inputStr  
                ",   inputInt: "   inputInt  
                ",   paramOutsideJNLPFile: "   inputOutsideJNLPFile;
        JLabel lbl = new JLabel(text);
        add(lbl);
    }
}

下面显示了 AppletTakesParams applet。

//<![CDATA[ var attributes = { code:‘AppletTakesParams.class’, archive:‘examples/dist/applet_AppletWithParameters/applet_AppletWithParameters.jar’, width:800, height:50} ; var parameters = { jnlp_href: ‘examples/dist/applet_AppletWithParameters/applettakesparams.jnlp’, paramOutsideJNLPFile: ‘fooOutsideJNLP’ }; deployJava.runApplet(attributes, parameters, ‘1.6’); //]]>


注意: 如果你看不到 applet 运行,你需要安装至少 Java SE Development Kit (JDK) 6 update 10 版本。



注意: 如果你看不到示例运行,可能需要在浏览器中启用 JavaScript 解释器,以便部署工具包脚本能够正常运行。


下载源代码 以进一步进行实验。

显示短状态字符串

原文:docs.oracle.com/javase/tutorial/deployment/applet/showStatus.html

所有浏览器都允许 Java applets 显示一个简短的状态字符串。页面上的所有 Java applets 以及浏览器本身共享同一状态行。

永远不要将关键信息放在状态行中。如果许多用户可能需要该信息,请在 applet 区域内显示该信息。如果只有少数精通的用户可能需要该信息,请考虑将信息发送到标准输出(参见将诊断信息写入标准输出和错误流)。

状态行通常不太显眼,并且可能被其他 applets 或浏览器覆盖。因此,最好将其用于偶发的、短暂的信息。例如,一个加载多个图像文件的 applet 可能会显示当前正在加载的图像文件的名称。

Applets 使用showStatus方法显示状态行,该方法从Applet类继承到JApplet类。

这里是其使用示例:

代码语言:javascript复制
showStatus("MyApplet: Loading image file "   file);

注意: 不要在状态行中放置滚动文本。浏览器用户会觉得这种行为非常恼人。


在浏览器中显示文档

原文:docs.oracle.com/javase/tutorial/deployment/applet/browser.html

一个 Java 小程序可以使用 java.applet.AppletContext 类中的 showDocument 方法在浏览器窗口中加载网页。

以下是 showDocument 的两种形式:

代码语言:javascript复制
public void showDocument(java.net.URL *url*)
public void showDocument(java.net.URL *url*, String *targetWindow*)

showDocument 的单参数形式简单地指示浏览器显示指定 URL 的文档,而不指定显示文档的窗口。

showDocument 的双参数形式允许您指定显示文档的窗口或 HTML 框架。第二个参数可以有以下值之一:

  • "_blank" – 在一个新的、无名称的窗口中显示文档。
  • "*windowName*" – 在名为 windowName 的窗口中显示文档。如有必要,将创建此窗口。
  • "_self" – 在包含小程序的窗口和框架中显示文档。
  • "_parent" – 在小程序框架的父框架中显示文档。如果小程序框架没有父框架,则与 "_self" 相同。
  • "_top" – 在顶层框架中显示文档。如果小程序框架是顶层框架,则与 "_self" 相同。

注意: 在这个讨论中,frame 指的不是一个 Swing JFrame,而是浏览器窗口内的 HTML 框架。


以下小程序使您可以尝试 showDocument 两种形式的每个参数。该小程序打开一个窗口,让您输入 URL 并选择 targetWindow 参数的选项。当您按下 Return 键或点击显示文档按钮时,小程序调用 showDocument

//<![CDATA[ var attributes = { code:‘ShowDocument.class’, archive:‘examples/dist/applet_ShowDocument/applet_ShowDocument.jar’, width:200, height:30} ; var parameters = { permissions:‘sandbox’ } ; deployJava.runApplet(attributes, parameters, ‘1.4’); //]]>


注意: 如果您看不到示例运行,可能需要在浏览器中启用 JavaScript 解释器,以便部署工具包脚本能够正常运行。


以下是调用 showDocument 的小程序代码。这是整个程序,ShowDocument

代码语言:javascript复制
        *...//In an Applet subclass:*
        urlWindow = new URLWindow(getAppletContext());
        . . .

class URLWindow extends Frame {
    ...
    public URLWindow(AppletContext appletContext) {
        ...
        this.appletContext = appletContext;
        ...
    }
    ...
    public boolean action(Event event, Object o) {
        ...
            String urlString =
                */* user-entered string */*;
            URL url = null;
            try {
                url = new URL(urlString);
            } catch (MalformedURLException e) {
                *...//Inform the user and return...*
            }

            if (url != null) {
                if (*/* user doesn't want to specify
                           the window */*) {
                    appletContext.showDocument(url);
                } else {
                    appletContext.showDocument(url,
                        */* user-specified window */*);
                }
            }
        ...

下载源代码 以进一步尝试 Show Document 示例。

从小程序调用 JavaScript 代码

原文:docs.oracle.com/javase/tutorial/deployment/applet/invokingJavaScriptFromApplet.html

Java 小程序可以调用与小程序在同一网页中的 JavaScript 函数。LiveConnect 规范描述了 JavaScript 代码如何与 Java 代码通信的详细信息。

netscape.javascript.JSObject类使 Java 小程序能够检索对 JavaScript 对象的引用并与网页交互。接下来描述的数据摘要小程序调用 JavaScript 代码从网页中检索信息,并将数据摘要写回网页。

假设您有一个带有几个 JavaScript 函数的网页。示例AppletPage.html具有用于检索年龄、地址和电话号码的 JavaScript 函数。还有一个名为userName的变量,一开始没有值。

代码语言:javascript复制
<head>
<title>Data Summary Applet Page - Java to JavaScript LiveConnect</title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"/>
<script language="javascript">
    var userName = "";

    // returns number
    function getAge() { 
        return 25;
    }
    // returns an object
    function address() { 
        this.street = "1 Example Lane";
        this.city = "Santa Clara";
        this.state = "CA";
    }
    // returns an array
    function getPhoneNums() { 
        return ["408-555-0100", "408-555-0102"];
    } 
    function writeSummary(summary) {
        summaryElem =
            document.getElementById("summary");
        summaryElem.innerHTML = summary;
    }
    </script>

    <!-- ... -->      
</head>
<body>
    <script src =
      "https://www.java.com/js/deployJava.js"></script>
    <script> 
        <!-- ... -->
        deployJava.runApplet(attributes, parameters, '1.6'); 
    </script>          
    <!-- ... -->
    <p id="summary"/>  // this HTML element contains
                             // the summary 
    <!-- ... -->
</body>

接下来,考虑一个名为DataSummaryApplet的小程序类。DataSummaryApplet类执行以下操作。

  • 调用JSObjectsetMember方法将userName变量设置为"John Doe"。
  • 检索年龄、地址和电话号码,并构建包含这些数据摘要的字符串。
  • 调用writeSummary JavaScript 函数将摘要写回网页。

该小程序首先需要按以下方式检索对JSObject的引用:

代码语言:javascript复制
...
JSObject window = JSObject.getWindow(this);
...

将前述语句放入 try…catch…块中以处理netscape.javascript.JSException

现在,小程序已经有了对JSObject的引用,它可以通过JSObjectevalcall方法调用相关的 JavaScript 函数。

代码语言:javascript复制
package javatojs;

import java.applet.Applet;
import netscape.javascript.*; // add plugin.jar to classpath during compilation

public class DataSummaryApplet extends Applet {
    public void start() {
        try {
            JSObject window = JSObject.getWindow(this);

            String userName = "John Doe";

            // set JavaScript variable
            window.setMember("userName", userName);

            // invoke JavaScript function
            Number age = (Number) window.eval("getAge()");

            // get a JavaScript object and retrieve its contents
            JSObject address = (JSObject) window.eval("new address();");
            String addressStr = (String) address.getMember("street")   ", "  
                    (String) address.getMember("city")   ", "  
                    (String) address.getMember("state");

            // get an array from JavaScript and retrieve its contents
            JSObject phoneNums = (JSObject) window.eval("getPhoneNums()");
            String phoneNumStr = (String) phoneNums.getSlot(0)   ", "  
                    (String) phoneNums.getSlot(1);

            // dynamically change HTML in page; write data summary
            String summary = userName   " : "   age   " : "  
                    addressStr   " : "   phoneNumStr;
            window.call("writeSummary", new Object[] {summary})   ;
        } catch (JSException jse) {
            jse.printStackTrace();
        }
    }
}

要编译具有对netscape.javascript包中类的引用的 Java 代码,请在类路径中包含<您的 JDK 路径>/jre/lib/plugin.jar。在运行时,Java 插件软件会自动使这些类对小程序可用。

数据摘要小程序在网页上显示以下结果:

代码语言:javascript复制
Result of applet's Java calls to JavaScript on this page

John Doe : 25 : 1 Example Lane, Santa Clara, CA : 408-555-0100, 408-555-0102

在浏览器中打开AppletPage.html以查看数据摘要小程序。


注意: 如果您看不到小程序运行,请安装至少Java SE Development Kit (JDK) 6 update 10版本。



注意: 如果您看不到示例运行,请确保在浏览器中启用 JavaScript 解释器,以便部署工具包脚本能够正常运行。


下载源代码以进一步实验从小程序调用 JavaScript 代码示例。

从 JavaScript 代码调用 Applet 方法

原文:docs.oracle.com/javase/tutorial/deployment/applet/invokingAppletMethodsFromJavaScript.html

网页上的 JavaScript 代码可以与嵌入在页面上的 Java applet 进行交互。JavaScript 代码可以执行以下操作:

  • 调用 Java 对象上的方法
  • 获取并设置 Java 对象中的字段
  • 获取和设置 Java 数组元素

LiveConnect 规范描述了 JavaScript 代码如何与 Java 代码通信的详细信息。

当 JavaScript 代码调用 Java applet 时,会显示安全警告。要抑制这些警告,需要在 JAR 文件清单中添加Caller-Allowable-Codebase属性。指定允许调用 applet 的 JavaScript 代码的位置。有关Caller-Allowable-Codebase属性的信息,请参阅安全的 JAR 文件清单属性。

本主题探讨了使用 Math applet 示例进行 JavaScript 代码到 Java applet 通信。MathApplet类和支持的Calculator类提供了一组公共方法和变量。网页上的 JavaScript 代码调用和评估这些公共成员以传递数据并检索计算结果。

Math Applet 和相关类

这是MathApplet类的源代码。getCalculator方法返回Calculator辅助类的引用。

代码语言:javascript复制
package jstojava;
import java.applet.Applet;

public class MathApplet extends Applet{

    public String userName = null;

    public String getGreeting() {
        return "Hello "   userName;
    }

    public Calculator getCalculator() {
        return new Calculator();
    } 

    public DateHelper getDateHelper() {
        return new DateHelper();
    }

    public void printOut(String text) {
        System.out.println(text);
    }
}

Calculator类中的方法允许用户设置两个值,相加数字,并在范围内检索数字。

代码语言:javascript复制
package jstojava;

public class Calculator {
    private int a = 0;
    private int b = 0; // assume b > a

    public void setNums(int numA, int numB) {
        a = numA;
        b = numB;
    }

    public int add() {
        return a   b;
    }

    public int [] getNumInRange() {    
        int x = a;
        int len = (b - a)   1;
        int [] range = new int [len];
        for (int i = 0; i < len; i  ) {
            range[i]= x  ;
            System.out.println("i: "   i   " ; range[i]: "   range[i]);
        }
        return range;
    }
}

DateHelper类的getDate方法返回当前日期。

代码语言:javascript复制
package jstojava;
import java.util.Date;
import java.text.SimpleDateFormat;

public class DateHelper {

    public static String label = null;

    public String getDate() {
        return label   " "   new SimpleDateFormat().format(new Date());
    }

}

部署 Applet

在网页中部署 applet,AppletPage.html。部署 applet 时,请确保为 applet 指定一个 id。稍后将使用 applet id 获取对 applet 对象的引用。

代码语言:javascript复制
<script src=
  "https://www.java.com/js/deployJava.js"></script>
<script>
    <!-- applet id can be used to get a reference to
    the applet object -->
    var attributes = { id:'mathApplet',
        code:'jstojava.MathApplet',  width:1, height:1} ;
    var parameters = { jnlp_href: 'math_applet.jnlp'} ;
    deployJava.runApplet(attributes, parameters, '1.6');
</script>

接下来,在AppletPage.html网页中添加一些 JavaScript 代码。JavaScript 代码可以使用 applet id 作为对 applet 对象的引用,并调用 applet 的方法。在下面的示例中,JavaScript 代码设置了 applet 的公共成员变量,调用了公共方法,并检索了由 applet 引用的另一个对象(Calculator)的引用。JavaScript 代码能够处理基本类型、数组和对象返回类型。

代码语言:javascript复制
<script language="javascript">
    function enterNums(){
        var numA = prompt('Enter number 'a'?','0');
        var numB = prompt(
            'Enter number 'b' (should be greater than number 'a' ?','1');
        // set applet's public variable
        mathApplet.userName = "John Doe";

        // invoke public applet method
        var greeting = mathApplet.getGreeting();

        // get another class referenced by applet and
        // invoke its methods
        var calculator = mathApplet.getCalculator();
        calculator.setNums(numA, numB);

        // primitive datatype returned by applet
        var sum = calculator.add();

        // array returned by applet
        var numRange = calculator.getNumInRange();

        // check Java console log for this message
        mathApplet.printOut("Testing printing to System.out");

        // get another class, set static field and invoke its methods
        var dateHelper = mathApplet.getDateHelper();
        dateHelper.label = "Today's date is: ";
        var dateStr = dateHelper.getDate();
        <!-- ... -->
</script>

当数字 a = 0 和 b = 5 时,Math applet 在网页上显示以下结果:

代码语言:javascript复制
Results of JavaScript to Java Communication

Hello John Doe

a = 0 ; b = 5

Sum: 5

Numbers in range array: [ 0, 1, 2, 3, 4, 5 ]

Today's date is: 5/28/13 4:12 PM //*shows current date*

在浏览器中打开AppletPage.html以查看数学小程序。


注意: 如果您看不到小程序运行,请至少安装Java SE 开发工具包(JDK)6 更新 10版本。



注意: 如果您看不到示例运行,请确保在浏览器中启用 JavaScript 解释器,以便部署工具包脚本能够正常运行。


检查由 JavaScript 代码调用的小程序所受到的安全限制。

下载源代码以进一步进行实验的通过 JavaScript 代码调用小程序方法示例。

使用事件处理程序处理初始化状态

原文:docs.oracle.com/javase/tutorial/deployment/applet/appletStatus.html

在 applet 初始化之前,applet 无法处理来自网页中 JavaScript 代码的请求。从 JavaScript 代码调用 applet 方法或访问 applet 变量将被阻塞,直到 applet 的init()方法完成或 applet 首次从部署的网页中调用 JavaScript 代码。由于许多浏览器中 JavaScript 实现是单线程的,因此在 applet 启动期间,网页可能会出现冻结的情况。

从 JDK 7 版本开始,您可以在 applet 加载时检查status变量,以确定 applet 是否准备好处理来自 JavaScript 代码的请求。您还可以注册事件处理程序,在 applet 初始化的各个阶段自动调用。为了利用这个功能,应该将 applet 部署时的java_status_events参数设置为"true"

在状态和事件处理程序示例中,JavaScript 代码向 applet 注册了一个onLoad处理程序。当 applet 初始化完成时,Java 插件软件会自动调用onLoad处理程序。onLoad处理程序调用 applet 的其他方法,在网页上绘制图形。DrawingApplet 类的init方法休眠两秒,模拟长时间的 applet 初始化过程。

以下步骤描述了如何注册事件处理程序并检查 applet 的状态。请参阅Applet 状态和事件处理程序,了解可以注册事件处理程序的完整的 applet 状态值和 applet 事件列表。

创建一个 JavaScript 函数来注册事件处理程序。以下代码片段显示了registerAppletStateHandler函数,如果 applet 尚未加载,则注册一个onLoad事件处理程序。

代码语言:javascript复制
<script>
<!-- ... -->
    var READY = 2;
    function registerAppletStateHandler() {
        // register onLoad handler if applet has
        // not loaded yet
        if (drawApplet.status < READY)  {                 
            drawApplet.onLoad = onLoadHandler;
        } else if (drawApplet.status >= READY) {
            // applet has already loaded or there
            // was an error
            document.getElementById("mydiv").innerHTML = 
              "Applet event handler not registered because applet status is: "
                 drawApplet.status;    
        }
    }

    function onLoadHandler() {
        // event handler for ready state
        document.getElementById("mydiv").innerHTML =
            "Applet has loaded";
        draw();
    }
<!-- ... -->
</script>        

body标签的 onload 方法中调用先前创建的registerAppletStateHandler函数。这样可以确保在注册 applet 的事件处理程序之前,applet 的 HTML 标签已经在网页的文档对象模型(DOM)树中创建。

代码语言:javascript复制
<body onload="registerAppletStateHandler()">

将 applet 部署时的java_status_events参数设置为"true"

代码语言:javascript复制
<script src=
  "https://www.java.com/js/deployJava.js"></script>
<script>
    // set java_status_events parameter to true 
    var attributes = { id:'drawApplet',
        code:'DrawingApplet.class',
        archive: 'applet_StatusAndCallback.jar',
        width:600, height:400} ;
    var parameters = {java_status_events: 'true', permissions:'sandbox' } ;
    deployJava.runApplet(attributes, parameters, '1.7');
</script>

在浏览器中打开AppletPage.html以查看 applet 事件处理程序的行为。在AppletPageUpdatedDuringLoading.html页面中,检查 applet 的status变量以确定 applet 是否已加载。根据状态,当 applet 被加载时,网页会持续更新。


注意: 如果您看不到 applet 运行,请安装至少 Java SE Development Kit (JDK) 7 版本。



注意: 如果您看不到示例运行,您可能需要在浏览器中启用 JavaScript 解释器,以便 Deployment Toolkit 脚本能够正常运行。


下载源代码 以进一步进行实验的 状态和事件处理程序 示例。

操作小程序网页的 DOM

原文:docs.oracle.com/javase/tutorial/deployment/applet/manipulatingDOMFromApplet.html

每个网页由一系列嵌套对象组成。这些对象构成了文档对象模型(DOM)。Java 小程序可以使用Common DOM API遍历和修改其父网页的对象。

考虑一个 Java 小程序的示例,它会转储其父网页的内容。

为了遍历和操作 DOM 树,您必须首先获取网页的Document对象的引用。您可以使用com.sun.java.browser.plugin2.DOM类中的getDocument方法来实现。以下是在DOMDump小程序的start方法中检索Document对象引用的代码片段。请查看代码中的内联注释。

代码语言:javascript复制
public void start() {
    try {
        // use reflection to get document
        Class c =
          Class.forName("com.sun.java.browser.plugin2.DOM");
        Method m = c.getMethod("getDocument",
          new Class[] { java.applet.Applet.class });

        // cast object returned as HTMLDocument;
        // then traverse or modify DOM
        HTMLDocument doc = (HTMLDocument) m.invoke(null,
            new Object[] { this });
        HTMLBodyElement body =
            (HTMLBodyElement) doc.getBody();
        dump(body, INDENT);
    } catch (Exception e) {
        System.out.println("New Java Plug-In not available");
        // In this case, you could fallback to the old
        // bootstrapping mechanism available in the
        // com.sun.java.browser.plugin.dom package
    }
}

现在您已经获得了Document对象的引用,您可以使用 Common DOM API 遍历和修改 DOM 树。DOMDump小程序遍历 DOM 树并将其内容写入 Java 控制台日志。

代码语言:javascript复制
private void dump(Node root, String prefix) {
    if (root instanceof Element) {
        System.out.println(prefix  
            ((Element) root).getTagName()   
            " / "   root.getClass().getName());
    } else if (root instanceof CharacterData) {
        String data =
            ((CharacterData) root).getData().trim();
        if (!data.equals("")) {
            System.out.println(prefix  
                "CharacterData: "   data);
        }
    } else {
        System.out.println(prefix  
            root.getClass().getName());
    }
    NamedNodeMap attrs = root.getAttributes();
    if (attrs != null) {
        int len = attrs.getLength();
        for (int i = 0; i < len; i  ) {
            Node attr = attrs.item(i);
            System.out.print(prefix   HALF_INDENT  
                "attribute "   i   ": "  
                attr.getNodeName());
            if (attr instanceof Attr) {
                System.out.print(" = "  
                    ((Attr) attr).getValue());
            }
            System.out.println();
        }
    }

    if (root.hasChildNodes()) {
        NodeList children = root.getChildNodes();
        if (children != null) {
            int len = children.getLength();
            for (int i = 0; i < len; i  ) {
                dump(children.item(i), prefix  
                    INDENT);
            }
        }
    }
}

在浏览器中打开AppletPage.html以查看DOMDump小程序的运行情况。检查 Java 控制台日志以获取网页 DOM 树的转储。


注意: 如果您看不到小程序运行,请至少安装Java SE Development Kit (JDK) 6 update 10版本。



注意: 如果您看不到示例运行,您可能需要在浏览器中启用 JavaScript 解释器,以便 Deployment Toolkit 脚本能够正常运行。


下载源代码以进一步进行实验的DOM Dump示例。

0 人点赞