Displaying and editing large (styled) texts


A reoccuring question in stackoverflow is how to present:

  • Large amounts of editable text
  • Display text paragraphs with words in different colors, sizes, … and optionally make them editable

In the following post I’d like to shade some light into this area of JavaFX and propose solutions allowing you to deal with them efficiently using runtime components developed as part of e(fx)clipse.

Displaying text

First of all to represent text the basic JavaFX classes you need to be aware of are:

  • javafx.scene.text.Text: Allows you to render a text chunk with a given color, font-size, font-family, …
  • javafx.scene.text.TextFlow: Allows you to layout text nodes mixed with other content like images, shapes, …

So the first conclusion we could draw from this information is that to display styled text we create a TextFlow, put Text elements with different color & font settings into it, embed the TextFlow into a ScrollPane and are done.

If you implement this you get something like this:

screen_2

I’ve written more on this at https://tomsondev.bestsolution.at/2013/02/14/experimenting-with-textflow-from-javafx8/

Mission accomplished? Almost until you notice that performance for big amounts of styled text are horrendous because the complete text has to be renderer although you only see 60 lines! Other problems: E.g. you don’t have a cursor so selecting and copying lines from the text are not possible. Bottom line: We need to get smarter but before we do so we look into editing of text.

Editing text

There are 3 main built-in controls to edit text:

  • javafx.scene.control.TextField: Edit a single line of text
  • javafx.scene.control.TextArea: Edit multi line text
  • javafx.scene.web.HTMLEditor: Edit styled text with the help of WebView

HTMLEditor solves a very special usecase so I’m not looking into it in this post. TextField is only for one line so there’s only TextArea left for larger chunks of text but TextArea has multiple draw backs:

  • You can not have different styled areas the complete text has to have one font, color, …
  • It is totally inefficient because for rendering it uses 1 big Text-Object, for a few lines this is ok but if you have text with more than thousand lines you’ll run into troubles

To sum up: JavaFX comes by default with NO control that allows you edit & display large text.

Text editing extensions coming with e(fx)clipse

Displaying small amount of styled text

In the upcoming 1.2.0 release we’ll provide you org.eclipse.fx.ui.controls.styledtext.StyledString which implements the CharSequence interface and a static helper which allows to generate a scenegraph node from it.

Useage looks like this:

StyledString s = new StyledString();
s.appendSegment("This","default-text");
s.appendSegment("is bold","bold-text");
s.appendSegment("and red","red-text");
s.appendSegment("and bold & red","bold-text","red-text");
Node n = Util.toNode(s);
// ...

The 2nd, 3rd, … argument are CSS-Styleclasses!

Displaying and editing large amounts of text

While the above method is easy to use it is not solving the problem for large texts (styled or not) nor does it help you with editing, … in fact it simply uses the TextFlow approach hiding the details from you.

To solve the problem of editing and displaying large text we need a control who virtualizes the Text-Elements to display and only the lines visible in the UI are part of the Scenegraph. Implementing something like this is not hard but it also is not needed because JavaFX comes with controls who work like this: All *View controls like TableView, ListView and TreeView are virtual in the sense that they only create as many ListCell, TreeCell, … as you see on screen.

Based upon this knowledge we implemented a StyledTextArea which has a similar API than SWT-StyledText to display and edit large styled texts, rendering 100,000 lines of code works in no time!

Useage is as simple as:

StyledTextArea t = new StyledTextArea();
t.getStylesheets().add(getClass().getResource("test.css").toExternalForm());
t.getContent().setText("This is a styled text!\nThis is the 2nd line with data\nBlaBla");
t.setStyleRanges(
    new StyleRange("text-highlight",0,30,null,null)
  , new StyleRange("text-highlight",34,5,null,null)
);
This entry was posted in e(fx)clipse. Bookmark the permalink.

13 Responses to Displaying and editing large (styled) texts

  1. Pingback: JavaFX links of the week, January 12 // JavaFX News, Demos and Insight // FX Experience

  2. Jim says:

    Hi Tom,

    Is your StyledTextArea still based on TextFlow? Do you have the code posted somewhere?

    Thanks,

    Jim

  3. Brian Stallter says:

    I’m pretty interested in this solution for a large editable text area with ability to add images. It would be a really nice solution, but the link above is pretty unclear and the explanation above kind of leaves off suddenly without really clearly outlineing the final code.

    • Tom Schindl says:

      look at the latest post on this blog to get more information about our control – still I guess it is not suitable for your needs as we are NOT providing support to add images, … . we are currently concentrating our efforts on a widget to develop code-editors

  4. Pat says:

    Your example shows a StyledTextArea consisting of two (short) lines of text, The topic of this blog is supposed to address displaying large amounts of styled text. Please show an example of how you support over 100,000 lines of text. I tried to use your StyledTextArea with a 16Mb file and it basically behaves the same way that the basic JavaFx TextArea does — namely it locks up the application because it can’t handle and can’t “virtualize” the content of the file that isn’t displayed.

  5. Andrew says:

    Does Java FX 12 come with a built-in solution to this issue?

  6. Piotr Gryko says:

    Hi, is it possible to add click listener for StyleRange ?

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.