0

JavaHelp 是 Sun 编写的一个库,用于在 Swing 应用程序中显示 HTML 帮助页面。JavaHelp 允许将 Swing 组件嵌入到其 HTML 页面中:

<html>
<object classid="java:javax.swing.JButton">
   <param name="text" value="Wow, a Swing component in HTML HTML!">
</object>
</html>

此处进一步讨论:http: //docs.oracle.com/cd/E19253-01/819-0913/dev/lwcomp.html

我在 Apache Felix 中运行一个大型 OSGi 应用程序。如上图,classid属性指的是我要嵌入的Swing组件类的FQN。我希望它引用我在自己的包中定义的 Swing 组件类。因为 JavaHelp 在它自己的包中运行,所以它不能引用我的包中的类。我只是??在HTML页面中看到,表示找不到该类。如何让 JavaHelp 包引用我的包中的类?

4

1 回答 1

2

这只是部分可能的。这就是为什么。

要解决这个问题,我们必须创建自己HTMLEditorKit的拦截object标签,然后Componentobject标签的classid. 这是它的样子*。

public class OurHTMLEditorKit extends HTMLEditorKit {
    public ViewFactory getViewFactory() {
        return new HTMLEditorKit.HTMLFactory() {
            public View create(Element elem) {
                if (elem.getName().equalsIgnoreCase("object"))
                    return new InternalObjectView(elem);
                else
                    return super.create(elem);
            }
        };
    }
}

private static Object attemptToGetClass(final String className) {
    try {
        Class c = Class.forName(className);
        Object o = c.newInstance();
        return o;
    } catch (Exception e) {
        logger.error(e.getMessage());
    }
    return null;
}


private static class InternalObjectView extends ObjectView {
    public InternalObjectView(Element elem) {
        super(elem);
        logger.info(elem.toString());
    }

    protected Component createComponent() {
        AttributeSet attrs = getElement().getAttributes();
        String classname = ((String) attrs.getAttribute(HTML.Attribute.CLASSID)).trim();
        try {
            Component comp = (Component) attemptToGetClass(classname);
            setParameters(comp, attrs);
            return comp;
        } catch (Exception e) {
            logger.warn(e.getMessage());
        }
        return getUnloadableRepresentation();
    }

    // Copied from javax.swing.text.html.ObjectView with modifications to how exceptions are reported

    Component getUnloadableRepresentation() {
        Component comp = new JLabel("??");
        comp.setForeground(Color.red);
        return comp;
    }

    private void setParameters(Component comp, AttributeSet attr) {
        Class k = comp.getClass();
        BeanInfo bi;
        try {
            bi = Introspector.getBeanInfo(k);
        } catch (IntrospectionException ex) {
            logger.warn("introspector failed, ex: "+ex);
            return;             // quit for now
        }
        PropertyDescriptor props[] = bi.getPropertyDescriptors();
        for (int i=0; i < props.length; i++) {
            //      System.err.println("checking on props[i]: "+props[i].getName());
            Object v = attr.getAttribute(props[i].getName());
            if (v instanceof String) {
                // found a property parameter
                String value = (String) v;
                Method writer = props[i].getWriteMethod();
                if (writer == null) {
                    // read-only property. ignore
                    return;     // for now
                }
                Class[] params = writer.getParameterTypes();
                if (params.length != 1) {
                    // zero or more than one argument, ignore
                    return;     // for now
                }
                Object [] args = { value };
                try {
                    writer.invoke(comp, args);
                } catch (Exception ex) {
                    logger.warn("Invocation failed: " + ex.getMessage());
                    // invocation code
                }
            }
        }
    }
}

但是使用 JavaHelp,不可能HTMLEditorKit使用<viewregistry>标签 [2] 来注册我们的。由于 OSGi 环境,JavaHelp 无法访问我们的HTMLEditorKit**。

相反,唯一可能的方法是JEditorPane使用我们的 创建一个,使用HTMLEditorKit创建我们自己的目录,并告诉在选择更改时加载帮助页面。JTreeTOCView.parse()JEditorPaneJTree


*这似乎很长,但大部分代码是从javax.swing.text.html.ObjectView[1]复制而来的。我不得不从那里复制代码,因为getUnloadableRepresentationsetParameters是私有的,不受保护。

**由于Dynamic-ImportPackage清单条目 [3],这可能是可能的。但这需要跳很多圈。首先,必须更改 JavaHelp 清单。其次,Felix 启动后,必须使用命令告诉它允许动态导入dynamic-import

  1. http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/javax/swing/text/html/ObjectView.java#ObjectView
  2. http://docs.oracle.com/cd/E19253-01/819-0913/author/helpset.html#toolbar
  3. http://wiki.osgi.org/wiki/DynamicImport-Package
于 2012-07-25T23:15:16.140 回答