首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

创建一种声明性 XML UI 语言 -6

创建一种声明性 XML UI 语言 -6

绑定最后一个需要研究的代码部分是处理运行时绑定。调用 XUI 对象的 bind 方法时,BindingFactory 的一个实例将被调用。
要将模型代码绑定到已构造的 GUI,BindingFactory 的 doBinding 方法(见 )必须执行以下操作:   
  • 捕获 URL,无论在本地、Internet 上或相对位置。
  • 通过 JarURLConnection 类检查 JAR 并使用一个单独的自定义类加载器加载类。
  • 从加载的 XML 文档查找一个类,它匹配 Resource 元素的 class 属性的名称。这个类是模型的入口点。
  • 使用 Java 反射框架实例化这个充当入口点的类并调用它的 init 方法。init 方法在概念上类似于一个典型 Java 类的 main 方法,因为它们都是入口点。
  • 如果 JAR 文件包含图像,还需要将图像载入内存。
清单 7. BindingFactory 的 doBinding 方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
public void doBinding(XUINode resource, XUI xui) throws XUIBindingException,
    MalformedURLException, IOException {
    if(resource.getAttributeValue("type").equals("java")) {
        String className = resource.getAttributeValue("class");
        String aURLString = resource.getAttributeValue("uri");
        URL url = null;
        // get the url ... if it's not a valid URL, then try and grab
        // it as a relative URL (i.e. java.io.File). If that fails
        // re-throw the exception, it's toast
        try {
            url = new URL("jar:" + aURLString + "!/");
        } catch (MalformedURLException mue) {
            String s = "jar:file://" + new File(aURLString)
                .getAbsolutePath().replace("\\", "/") + "!/";
            url = new URL(s);
            if(url == null) {
                // it really was malformed after all
                throw new
                    MalformedURLException("Couldn't bind to: "
                    + aURLString);
            }
        }
        // get a jar connection
        JarURLConnection jarConnection = (JarURLConnection)url.openConnection();
        // get the jar file
        JarFile jarFile = jarConnection.getJarFile();
        // jar files have entries. Cycle through the entries until finding
        // the class sought after.
        Enumeration entries = jarFile.entries();
        // the class that will be the entry point into the model
        JarEntry modelClassEntry = null;
        Class modelClass = null;
        XUIClassLoader xuiLoader =
            new XUIClassLoader(this.getClass().getClassLoader());
        while(entries.hasMoreElements()) {
            JarEntry remoteClass = (JarEntry)entries.nextElement();
            // load the classes
            if(remoteClass.getName().endsWith(".class")) {
                // have to get the second last word between period marks. This
                // is because the convention allows for:
                // org.purnamaproject.xui.XUI
                // that is, the periods can represent packages.
                StringTokenizer st =
                    new StringTokenizer(remoteClass.getName(), ".");
                String previousToken = st.nextToken();
                String currentToken = "";
                String nameOfClassToLoad = previousToken;
                while(st.hasMoreTokens()) {
                    currentToken = st.nextToken();
                    if(currentToken.equals("class"))
                        nameOfClassToLoad = previousToken;
                    else {
                        nameOfClassToLoad += currentToken;
                    }
                }
                // get an output stream (byte based) attach it to the
                //inputstream from the jar file based on the jar entry.
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                InputStream is = jarFile.getInputStream(remoteClass);
                final byte[] bytes = new byte[1024];
                int read = 0;
                while ((read = is.read(bytes)) >= 0) {
                    baos.write(bytes, 0, read);
                }
                Class c = xuiLoader.getXUIClass(nameOfClassToLoad, baos);
                // check for the class that has the init method.
                if(remoteClass.getName().equals(className + ".class")) {
                    modelClassEntry = remoteClass;
                    modelClass = c;
                }
            } else {
                String imageNameLowerCase = remoteClass.getName().toLowerCase();
                if(imageNameLowerCase.endsWith(".jpeg")
                    || imageNameLowerCase.endsWith(".jpg")
                    || imageNameLowerCase.endsWith(".gif")
                    || imageNameLowerCase.endsWith(".png")) {
                    // add resources (images)
                    XUIResources.getInstance().addResource(remoteClass, jarFile);
                }
            }
        }
        // now instantiate the model.
        try {
            // create a new instance of this class
            Object o = modelClass.newInstance();
            // get the method called 'init'. This is part of the API
            // requirement
            Method m = modelClass.getMethod("init", new Class[] {XUI.class});
            // at last, call the method up.
            m.invoke(o, new Object[] {xui});

        } catch(InstantiationException ie) {
            ie.printStackTrace();

        } catch(IllegalAccessException iae) {
            iae.printStackTrace();

        } catch(NoSuchMethodException nsm) {
            nsm.printStackTrace();

        } catch(InvocationTargetException ite) {
            System.out.println(ite.getTargetException());
            ite.printStackTrace();
        }
    } else {
        throw new XUIBindingException(
            "This platform/API requires Java libraries.");
    }
}




检查这个框架的机制后,现在让我们测试一下这个框架并展示一个应用程序示例。
返回列表