Search code examples
vaadinvaadin10vaadin-flow

How do I show a lot of text using Vaadin?


I need to process some data and show processing logs on a webpage. (Around 300 lines of text).
I tried to use labels. At first it worked fine - page became scrollable and all text could be seen. But after around 100 labels page became unresponsive.
How to manage this task?
(I tried to look for some other components on webcomponents.org but couldn't find anything.)


Solution

  • TextArea

    I tried one of the approaches mentioned in Answer by Leif Åstrand, using TextArea.

    When I preload with 300 short lines, no problem. Clicking a button to add 10 more lines at a time works without a hitch. Using the web browser’s window scroll bar to scroll up and down works smoothly.

    I used Vaadin 10.0.4 with Java 10.0.1 (Zulu by Azul Systems), in browser Safari 11.1.2 on macOS High Sierra on an external 4K monitor hooked up to a MacBook Pro Retina.

    Here is the entire Vaadin app.

    package com.basilbourque.example;
    
    import com.vaadin.flow.component.button.Button;
    import com.vaadin.flow.component.dependency.HtmlImport;
    import com.vaadin.flow.component.orderedlayout.VerticalLayout;
    import com.vaadin.flow.component.textfield.TextArea;
    import com.vaadin.flow.router.Route;
    
    import java.time.Instant;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    import java.util.stream.Collectors;
    
    /**
     * The main view contains a button and a template element.
     */
    @HtmlImport ( "styles/shared-styles.html" )
    @Route ( "" )
    public class MainView extends VerticalLayout {
        TextArea textArea;
    
        // Constructor.
        public MainView () {
            this.setWidth( "100%" );
    
            this.textArea = new TextArea( "Logs" );
            this.textArea.setWidth( "100%" );
            this.textArea.setReadOnly( true );
            this.appendRows( 300 );
    
            Button button = new Button( "Add 10 more rows" , event -> {
                this.appendRows( 10 );
            } );
    
            this.add( button , this.textArea );
            this.setClassName( "main-layout" );
        }
    
        private void appendRows ( int countRows ) {
            List< String > entries = new ArrayList<>( countRows );
            for ( int i = 1 ; i <= countRows ; i++ ) {
                entries.add( Instant.now().toString() );
            }
            Collections.reverse( entries ); // Put newest on top.
            String s = entries.stream().collect( Collectors.joining( "\n" ) );
            textArea.setValue( s + "\n" + this.textArea.getValue() );
        }
    }
    

    enter image description here