2012-07-24 27 views
0

JavaHelp是Sun編寫的一個庫,用於在Swing應用程序中顯示HTML幫助頁面。 JavaHelp的允許嵌入Swing組件到它的HTML頁面:在OSGi環境中將Swing組件嵌入JavaHelp頁面中?

<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中費利克斯大OSGi應用程序。如上所示,classid屬性是指我要嵌入的Swing組件類的FQN。我想這是指我在自己的包中定義的Swing組件類。因爲JavaHelp運行在它自己的包中,所以它不能引用我的包中的類。我只是在HTML頁面中看到??,表示找不到該類。我怎樣才能讓JavaHelp包引用我的包中的類?

+0

我懷疑這將是一個痛苦的經歷,因爲我覺得* *是JavaHelp的只是做了的Class.forName。你將不得不求助於動態導入,我不知道這是否值得。 – 2012-07-25 12:14:11

+0

是否需要修改JavaHelp jar以在清單中包含'Dynamic-PackageImport'條目,然後在Felix中使用'dynamic-import'命令?還是有更簡單的方法來做到這一點?我發現'dynamic-import'會導致其他bundle神奇地停止。而且JavaHelp仍然無法找到我的課程。 – 2012-07-25 19:13:07

+0

此外,事實證明,真正的罪魁禍首甚至不是在JavaHelp中,而是在'HTMLEditorKit'的'ObjectView'中:http://grepcode.com/file/repository.grepcode。COM /爪哇/根/ JDK /的openjdk/6-B14 /的javax /擺動/文本/ HTML/ObjectView.java#的ObjectView – 2012-07-25 19:36:09

回答

1

這只是部分可能的。這是爲什麼。

要解決這個問題,我們要創造我們自己的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>標籤我們HTMLEditorKit註冊[2]。由於OSGi環境,JavaHelp無法訪問我們的HTMLEditorKit **。

相反,唯一可行的方法是創建與我們HTMLEditorKit一個JEditorPane,通過使用TOCView.parse()創造我們自己的TOC JTree,並告訴JEditorPane加載幫助頁面時JTree的選擇更改。


*這似乎長,但大部分代碼從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