High performance text component

André Thieme a.thieme at freenet.de
Sun Aug 5 08:13:13 PDT 2012

Hello Felipe!

Am 03.08.2012 22:29, schrieb Felipe Heidrich:

> (I will just assume that you are developing a code editor (no embedded
> objects, bullet lists, tables, etc).)

Yes, what I want now is a rectangular area in which I can visualize and
Strings. Users can load code files, but also data files, such as .xml or
.csv or others. Such data files might be huge in size, say, over 50 MB
or so.
And I want to be able to display/organize hundreds of such CodePanes at
the same time. Most of them would contain only snippets and small
amounts of code. But I have to think about some extreme cases too.
It would not be acceptable for users if they were not be able to open
80 views on code at the same time, all between 1 and 5k LOC, and perhaps
a few 20 MB .csv files.

I don’t necessarily want to organize those CodePanes in tabs, as we can
see it in classical editors. Perhaps they will be floating free in space
(think more of Minority Report touch interfaces).

I also have to be able to “paint” over the texts. For example, instead
of underlining a word, I might want to display a pulsing and animated
ellipse around a single word or symbol, or group of words or code 
blocks. In this picture we see how a tooltip and some other small window
are painted above the code. We can also see those red arrows which point
to something. Those were added later, but in principle I should be able
to display them directly on top of the code, to draw the attention to
specific elements: http://goo.gl/7UicL

> I would go with option (1), I would use one Text node per line, and
> stack them vertically in a Pane.

That should give very nice performance, as there would be only max 80
Text instances visible, per CodePane at the same time.
A user could minimize those panes horizontally and display 20 of them
on a big widescreen monitor. Let’s make this 40, if he uses two big
widescreen monitors. So in the most extreme case this approach would
only require 80x40 = 3200 Text instances at the same time visible on
the screen.

However, this would unfortunately not work. Only in rare cases I would
be able to display a whole line of code with a single Text instance.
This is because “words” are partitioned into different classes, such as
Strings, vars, functions, operators, symbols, etc., so they can be
colored and styled independently.
I have to assume users want to bring the editor to its limits, by
putting only single operators/symbols into a code file, that all require
changing colors. Imagine a file of 20k pairs of parenthesis. When I want
to support paren highlightning, then each single paren will require its
own Text instance.
I will have to assume that a user might want to display a file which
would require me to have 20k or more Text instances visible at the same

> That is basically what I used for Eclipse (1 TextLayout per line) and
> Orion (1 div per line) http://eclipse.org/orion/.

Does a TextLayout allow you to do this:
tl = new TextLayout();
tl.setText("    private final int num = 33;")
//          0123456789012345678901234567890
tl.setColor(4, 11, Color.BLUE);    // private
tl.setColor(12, 17, Color.PURPLE); // final
tl.setColor(18, 21, Color.GREEN);  // int
tl.setStyle(18, 21, Font.BOLD);    // int (font style)
tl.setColor(22, 25, Color.BLACK);  // num
tl.setColor(26, 27, Color.RED);    // =
tl.setColor(28, 30, Color.CYAN);   // 33
tl.setBG(28, 30, Color.GRAY);      // 33 (bg color)
tl.setColor(30, 31, Color.RED);    // ;

If yes, then basically a TextLayout is more or less already a RichText?

> 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).

Hmm yes, that sounds plausible. Especially compacting styles/colors
could turn out to be useful. If several words in a line would be colored
and styled identically, then those words can be displayed in a single
Text instance, instead of multiple ones.

> Option (2) I think is implemented already, you can use javascript editor
> in the web node, there are many out there (orion, code mirror, see
> http://en.wikipedia.org/wiki/Comparison_of_JavaScript-based_source_code_editors)

Yes, using a WebView sounds more comfortable at first, than coming up
with something on my own, where I have virtual content and a view into
it, and manually managing ScrollPanes. However, I am not convinced how
well 200+ WebView instances would perform, and how easily I can
communicate with it. For example displaying a blinking cursor, where the
cursor can be either a slim vertical bar, or a full block that encloses
a single char. And can I catch all keyboard events inside it?
I am a bit sceptical here — a WebView might be a too “fat” building

> 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.

Do you already have an idea about the API for the RichText component?
Above I demonstrated the use of an example API. I would format the code
into a single String. In the case of a .csv file this String may contain
50 million chars. In the next step I would specify substrings via
start/end positions and their “style”. That is: font, bold, italic,
underline, overline, strikethrough, color, background color.
In principle every single char should be able to have its own unique
set of those attributes.

I could imagine a getStyles method, which returns an immutable sequence
of “Style” instances, where each Style has a start and end position, and
each of the above attributes.
A part of my example above:
tl = new TextLayout();
tl.setText("    private final int num = 33;")
//          0123456789012345678901234567890
tl.setColor(18, 21, Color.GREEN);  // int
tl.setStyle(18, 21, Font.BOLD);    // int (font style)
tl.setColor(22, 25, Color.BLACK);  // num
tl.setColor(26, 27, Color.RED);    // =

A call tl.getStyles(20, 28) would return the styles for the
"t num = " substring:
  <Sytle start=20, end=21, color=Color.GREEN, style=Font.BOLD>,
  <Style start=22, end=25, color=Color.BLACK>,
  <Style start=26, end=27, color=Color.RED>

And two more questions:
1) how does a Text instance paint its Text on the screen? Oracle uses 
some low-level API to get the text on screen somehow. Is there a chance
of opening up that API? The most low-level way to display texts seems
to be the Canvas so far.

2) how would you implement a RichText component? Would you use Text
instances, or Labels for it? Or rely on some JFX low-level API, which
allows you to do manipulations directly on the level of the graphics

Sunny greetings,

More information about the openjfx-dev mailing list