JavaHelp是Sun编写的一个库,用于在Swing应用程序中显示HTML帮助页。JavaHelp允许在其HTML页面中嵌入Swing组件:
<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。我希望它引用我在自己的bundle中定义的Swing组件类。因为JavaHelp在它自己的包中运行,所以它不能引用我的包中的类。我只在HTML页面中看到了??,表示找不到该类。如何让JavaHelp包引用我包中的类?
发布于 2012-07-26 07:15:16
这只是部分可能的。这就是为什么。
要解决这个问题,我们必须创建自己的HTMLEditorKit来拦截object标签,然后从object标签的classid创建自己的Component。看起来是这样的*。
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中,无法使用<viewregistry>标签2注册我们的HTMLEditorKit。由于OSGi环境,JavaHelp无法访问我们的HTMLEditorKit**。
相反,唯一可能的方法是使用我们的HTMLEditorKit创建一个JEditorPane,使用TOCView.parse()创建我们自己的目录JTree,并告诉JEditorPane在JTree的选择发生变化时加载帮助页面。
*这看起来很长,但大部分代码是从javax.swing.text.html.ObjectView 1复制的。我必须从那里复制代码,因为getUnloadableRepresentation和setParameters是私有的,而不是受保护的。
**由于Dynamic-ImportPackage清单条目3,这可能是可能的,但这需要经历很多困难。首先,必须更改JavaHelp清单。其次,在Felix启动之后,必须告诉它允许使用dynamic-import命令进行动态导入。
https://stackoverflow.com/questions/11640704
复制相似问题