Help

getting absolute position

I want to convert html's rendered snapshot to another xml format but it needs absolute position of each element. So, I planned to use cobra to get absolute position of each html element without real rendering to Swing GUI.
I think cobra support this operation, but I cannot find the way to get this information.

The information is there, but you might need to make some classes public. Each DOM element has a getUINode() method. This will normally return an instance of RElement, which in turn has a getBounds() method. The bounds are not absolute, but absolute bounds can be calculated by looking at ancestor bounds.

I have some questions again.
(1) it seems that Cobra rendering feature only works while real GUI window is appered. I've tested with frame.setVisible(false); but result of UINode.getBounds() is not correct. Is there another method to get position information without GUI window?
(2) In case of following html code, "font <b>strong</b> test", all getUINode() result are null - for "font", "<b>", "strong", and "test". How can I get the exact position of each #text node?

Hi again. The way it works is that there's a renderer tree that decorates the HTML DOM. The renderer tree is built when layout happens, specifically when HtmlBlockPanel.doLayout() is called (which should be called in the GUI thread). If getUINode() is null on a HTML DOM node, it means that layout has not occurred.

There is a way for you to create a renderer tree without creating a HtmlPanel or a HtmlBlockPanel. You can directly create an instance of RBlock and call one of its layout() methods. For that you do have to provide implementations of the RenderableContainer and FrameContext interfaces. RBlock will be the root of the tree and you can get children with the getRenderables() method.

Question about your reply. You said, if getUINode() is null, layout has not occurred. But I think text related node does not provide UINode infomation.
I have tested following html "<html><head><title>X</title></head><body> font <b>strong</b> test</body>" and get the result as below. <body> element returns UINode infomation, it means layout is done, I guess. This test code is called by AWT thread after window is displayed.

You're correct. Only block-level nodes have a UI node, e.g. divs, tables, table cells, lists, etc. You can find the position of a particular word (RWord) or a line (RLine) but it's not that easy to find the position of a text node or an inline node. It's easier to go from position to enclosing node.

Images do have UI nodes associated with them, so in your case that's doable. However, you need to have the document render first. Parsing is not enough.

To render, one way is to create a HtmlBlockPanel, call setRootNode on it, and then doLayout(). This should be done in the GUI thread, by calling EventQueue.invokeLater().

There's also a way to render without involving Swing components (other than Swing components that are necessarily created for inputs and images). See the method testRendererLoop() in MemoryTest.java. Basically, it does this:

Hi thank you for your help,
it was very easy to find what you told me. Here is part of the memorytest code that I use to find the position of the images. Now the UINode of every image is not null but the position returned by each UINode is 0.

I forgot to mention that the UINode bounds are relative to its parent. You need to cast UINode to BoundableRenderable and call getGUIPoint(0,0) instead. I went ahead and tested it. You can use the following code with 0.97.

Hi again.
I managed to get the Images, and Tables position.
Now I need to get the position of A nodes and TEXT nodes.
As I read in the previous post A and TEXT nodes doesnt have a UINODE associated with them so I cant get the position.

1)Is it possible to associate a UiNode and the position with those elements?
2)If so where should I start looking to implement it?

That's trickier. Only boxes and Swing controls have UINodes. Inline elements like A and SPAN do not.

It should be possible to get that information though. You need to traverse the renderer tree (whose root is the RBlock you created) instead. Every Renderable node (e.g. RWord) points to a DOM node (via modelNode). That's how you can find it.

I have read the whole discussion list, and tried the above example code out to get the image position successfully.
But have no idea "how to traverse the renderer tree" as mentioned at the last reply. Could you please give more detail explanation about this? Or where can i find the information.

RBlock is a tree root. You can get its children by calling RBlock.getRenderables(). That's an iterator of Renderable objects. If the Renderable casts to RCollection, you can call getRenderables() on it again. So it's not that hard to write a recursive method that traverses the whole renderer tree, getting positions for all renderable nodes therein. Does that help?

BTW, in 0.97.5 calling RBlock.layout() is not enough. There's RBlock.adjust() which completes some aspects of the layout process.

I am using Cobra 0.89.4 to get absolute positions of text nodes from this Web page:
"<HTML><TITLE>Some Country Codes</TITLE>
<BODY><B>Some Country Codes</B><P>
<B>Congo</B> <I>242</I><BR>
<B>Egypt</B> <I>20</I><BR>
<B>Belize</B> <I>501</I><BR>
<B>Spain</B> <I>34</I><BR>

<HR><B>End</B></BODY></HTML>
"
I have drawn the boxes generated by my code and I remarked that "Some Country Codes" and "Congo 242" are in the same line, but using firefox they are rendered in separated lines. I don't understand that ? is it a bug ?
thx for help.
here my code: