// Make sure most recent material visible, at the bottom.
// G O T C H A !
// Use invokeLater to give time for text to render
// after a JTextArea.setText before we process the setValue,
// otherwise the setValue will be effectively ignored.
// Must run on Swing thread.

instructions = new JEditorPane();
instructions.setName( "instructions" );
instructions.setContentType( "text/html" );
instructions.setBackground( INSTRUCTIONS_BACKGROUND );
instructions.setForeground( INSTRUCTIONS_FOREGROUND );
instructions.setFont( INSTRUCTIONS_FONT );
instructions.setAlignmentX( 0.5f );
instructions.setAlignmentY( 0.5f );
instructions.setMargin( new Insets( 4, 4, 4, 4 ) );
instructions.setEnabled( true );
instructions.setEditable( false );
final HTMLDocument htmlDocument = new HTMLDocument();
instructions.setDocument( htmlDocument );
instructions.setText( theInstructions );
instructionsScrollPane = new JScrollPane( instructions, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED );

// If you tried the set the vertical scroll position here, it might not work, since the text has not yet had time to render.

// invoke later to give time for text to render.
SwingUtilities.invokeLater( new Runnable()
                               {
                               public void run()
                                  {
                                  // Make sure the first line of the scroll region is visible.
                                  instructionsScrollPane.getVerticalScrollBar().setValue( 0 );
                                  }
                               } );

// to get bottom visible, use
final JScrollBar v = scroller.getVerticalScrollBar();
v.setValue( v.getMaximum() );