Missing spaces/tabulations in JTextPane with HTML content

802 Views Asked by At

I have two different JTextPanes, the first one is a log where different threads send messages. There are saved sessions in html files, these files are used as the content of the second JTextPane when the user loads them. Both of the JTextPanes have html content type.

At the first JTextPane I insert the new lines directly into the StyledDocument with the insertString() method. Everything is fine all spaces and tabulations are correct (before and after the "OFFLINE" tag): enter image description here

Here is a picture about a part of the html file from NotePad++, with Show All Characters function: enter image description here

The tabulations and the spaces are still there.

However, when I load back this file, and pass it to the second JTextPane it looks like this: enter image description here

Tabulations and spaces are gone. I have tried using &nbsp instead of simple spaces but the result is the same.

Second JTextPane's code:

    //settings
    eventLogHistory = new JTextPane();
    eventLogHistory.setEditable(false);
    eventLogHistory.setName("eventLogHistory");
    eventLogHistory.setContentType("text/html");

Code doing the loading:

File f=new File(directory+"eventlog.html");
if(f.exists()) 
{
    Scanner scan = new Scanner(f);
    String strtmp=new String();

    strtmp=scan.nextLine();
    strbld.append(strtmp+"\n");

    while(scan.hasNextLine()) 
    {
        strtmp=scan.nextLine();
        strbld.append(strtmp+"\n");
    }
    scan.close();

    getEventLogHistory().setText(strbld.toString());            
}

If I open the html file with Mozzila the tabulations and spaces are gone as well.

How can this be solved, what do I miss here?

Update As it can be seen in Andrew Thompson's answer I missed <pre> tags, thank you for the useful information. However these tags break the line and remove all style from the wrapped text. The following MCVE and sample input imitates the issue.

So the new question is: how can I avoid the previously described behaviour of the <pre> tag?

MCVE:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.DefaultCaret;

public class TextPaneWithHTML
{
    public TextPaneWithHTML()
    {
        final JFrame frame = new JFrame("JTextPane with HTML content");

        final JTextPane eventLogHistory = new JTextPane();
        eventLogHistory.setEditable(false);
        eventLogHistory.setName("eventLogHistory");
        eventLogHistory.setContentType("text/html");
        eventLogHistory.setForeground(Color.BLACK);

        JScrollPane messageTextScrollPane= new JScrollPane( eventLogHistory );
        messageTextScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        DefaultCaret caretMessageText = (DefaultCaret)eventLogHistory.getCaret();
        caretMessageText.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);

        final JFileChooser fc = new JFileChooser();

        JButton loadButton = new JButton("Load content");
        loadButton.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent arg0) 
            {
                StringBuilder strbld=new StringBuilder();

                int returnval=fc.showOpenDialog(frame);

                if (returnval == 0) 
                {                   
                    File f = fc.getSelectedFile();
                    try 
                    {
                        if(f.exists()) 
                        {
                            Scanner scan = new Scanner(f);
                            String strtmp=new String();

                            while(scan.hasNextLine()) 
                            {
                                strtmp=scan.nextLine();
                                strbld.append(strtmp+System.getProperty("line.separator"));

                            }
                            scan.close();

                            eventLogHistory.setText(strbld.toString());         
                        }           
                    } 
                    catch (IOException e)
                    {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }   
        });



        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);       
        frame.setSize(1200, 700);
        frame.getContentPane().add(messageTextScrollPane, BorderLayout.CENTER);
        frame.getContentPane().add(loadButton, BorderLayout.NORTH);

        frame.setVisible(true);

    }

    public static void main(String[] args)
    {
        new TextPaneWithHTML();
    }

}

Test input, copy this into a txt file and save as html:

<html>
 <head> 
 <style type="text/css"> 
.red{ color:#ff0000; }.blue{ color:#0000ff; }.green{ color:#33ff33; }.CLIgreen{ color:#02f002; }.khaki{ color:#8f8fff; }.white{ color:#ffffff; }.yellow{ color:#ffff00; }.pink{ color:#ff00ff; }.grey{ color:#d3d3d3; }.orange{ color:#ffc800; }p{ font-family: arial; font-size: 10; font-weight: bold; margin:0; } 
pre {
display:inline
}
 </style> 
 </head> 
<body>

<p><font class="white">[2014.11.17., 12:38:10]:  </font><font class="khaki">[TN-11111111]  [11111111]:  [cp1]   </font><font class="grey"><pre>OFFLINE          </pre></font><font class="white">  ----  </font><font class="green">SLAVE</font><font class="blue"></font></p>
<p><font class="white">[2014.11.17., 12:38:10]:  </font><font class="khaki">[TN-11111111]  [11111111]:  [cp2]   </font><font class="grey">OFFLINE          </font><font class="white">  ----  </font><font class="blue">MASTER</font>      
</p>
<p><font class="white">[2014.11.17., 12:38:10]:  </font><font class="khaki">[TN-11111111]  [11111111]:  [Clock] </font><font class="grey">OFFLINE          </font><font class="white">  ----  </font><font class="green">LOCKED</font><font class="blue"></font></p>
<p><font class="white">[2014.11.17., 12:38:10]:  </font><font class="khaki">[TN-11111112]  [11111112]:  [cp3]   </font><font class="grey">OFFLINE          </font><font class="white">  ----  </font><font class="green">SLAVE</font><font class="blue"></font></p>
<p><font class="white">[2014.11.17., 12:38:10]:  </font><font class="khaki">[TN-11111112]  [11111112]:  [cp4]   </font><font class="grey">OFFLINE          </font><font class="white">  ----  </font><font class="yellow">PASSIVE</font><font class="blue"></font></p>
<p><font class="white">[2014.11.17., 12:38:10]:  </font><font class="khaki">[TN-11111112]  [11111112]:  [cp2]   </font><font class="grey">OFFLINE          </font><font class="white">  ----  </font><font class="blue">MASTER</font>      
</p>
<p><font class="white">[2014.11.17., 12:38:10]:  </font><font class="khaki">[TN-11111112]  [11111112]:  [cp1]   </font><font class="grey">OFFLINE          </font><font class="white">  ----  </font><font class="blue">MASTER</font>      
</p>

  </body>
</html>

The <pre> tags are applied only for the first row and the line breaks at both <pre> and </pre>.

1

There are 1 best solutions below

3
On BEST ANSWER

..has html content type .. Tabulations and spaces are gone.

Yes. That would do it.

Unless the relevant text were wrapped in <pre> and </pre> to indicate a preformatted section of text, the spaces are normalized and tabs ignored.