High performance text component
felipe.heidrich at oracle.com
Fri Aug 3 13:29:31 PDT 2012
(I will just assume that you are developing a code editor (no embedded objects, bullet lists, tables, etc).)
I would go with option (1), I would use one Text node per line, and stack them vertically in a Pane.
That allows you to virtualize the content (only create Text for the lines that are visible), scrolls content moving the existent lines up and only creating nodes for new lines that show at the bottom, If you use fixed line height computing the scrollbars also should be pretty straightforward.
That is basically what I used for Eclipse (1 TextLayout per line) and Orion (1 div per line) http://eclipse.org/orion/.
Other consideration you will need to make is your data model, for Eclipse (and Orion) we used TextModel/AnnotationModel to plug data/control/and view together. Very important that these model allow you to compact data and to batch changes together (for example, instead of giving API to add a remove a style at the time, give a API that allows many styles to be removed and added with one single call, that will allow your view to do something smart).
Option (3) is what the bespin project tried to do for the web (using the html5 canvas), it failed (I don't know all the reasons), later bespin became skywriter, later it merged with ACE.
Personally I find this options hard as the html5 canvas does not have a very impressive API for Text.
In JFX we are working on adding Unicode support and rich text support (ranges of text with different attributes in the same paragraph). Note that the Text node is just a display element (like the TextLayout for StyledText, for a "div" element in a HTML page).
I have some ideas written down for our Rich Text API that I will be making available soon, stay tune.
On Aug 2, 2012, at 7:52 PM, André Thieme wrote:
> I would like to develop an editor component, think of NetBeans/Eclipse.
> There should be a surface on which one can display sharp LCD text. Lots
> of text. Users may wish to open 40 MB .csv files, perhaps on top of 200
> opened code files, of which some may contain 8k LOC.
> So far I have thought about different strategies:
> 1) A Group filled with javafx.scene.control.Label or
> javafx.scene.text.Text instances. This makes it very easy to detect
> where exactly a user clicked. It allows for giving each word or even
> symbol its own color, font, style, etc.
> This is obviously a difficult approach. The corresponding scenegraph
> might contain hundreds of thousands of nodes and won’t perform well.
> 2) WebViews.
> Those allow us also to colorize and style each word or symbol. But I do
> not know yet, how much control it will give me. Can I overlay words with
> my own graphics? For example, I may want to draw a pulsing elipse around
> a specific word, to draw the attention of the end user to it. I would
> have to know the exact coordinates of each single words. The bounds so
> to speak, baseline, etc.
> Also: how well do WebViews scale if I have 200+ of them in a ScrollPane?
> 3) Canvas + fillText
> I tried this one, and it is pretty performant. On my laptop I can write
> 15k words on a big Canvas in only 30 msecs. Unfortunately Canvas can at
> the moment only use “Gray” as Font smoothing style, not “LCD”. But while
> this may come in future versions it has two other limitations:
> it does not deliver boundaries information when fillText is called. So I
> was forced, in my experiments, to first setText a Text component, get
> its layout bounds, and then calculate the coordinates for fillText.
> The second limitation is the most difficult one: a Canvas is limited to
> 8192x8192 pixels resolution. With a small font this would be good for
> about 700 LOC.
> So, the Canvas that I would need should allow 1mio x 1mio resolution.
> An alternative technique would be to have hundreds of smaller Canvas’,
> in Google Maps style, and put them together somehow.
> All those alternatives don’t look really usable for me.
> One thing that would be interesting is to have access to low-level
> functions of the JFX API. How does a javafx.scene.text.Text instance
> paint its LCD text on the screen?
> In principle what I would need is an infinite surface on which I can
> write and manipulate text with maximum speed, without adding nodes to
> the scenegraph. Modern video cards can run 3d games with way over 60 FPS
> and render complex scenarios with light. It should be possible to
> display text that is at least as fast (I know that JFX caps at 60 FPS,
> but that is fine). So when I have a massive 30 MB file with hundreds of
> thousands of lines of text, all colored and styled depending on the
> file type (Java code, Python code, etc), and this should scroll and
> resize very fluid.
> If the JFX team wanted to write the editor component for Eclipse 5,
> how would you approach that? Most likely not by using one of the three
> strategies that I layed out above.
> Do you have any inputs for me?
> Sunny greetings,
More information about the openjfx-dev