Search code examples
javahtmljtextarea

How to generate html for text in JTextArea?


I have a problem in generating html code for a given string which is from

JTextArea textArea=new JTextArea(10,10);
String textToHtml=textArea.getText();

In this generated html code, it should contain with all html tags which are related to the given string.

Like <p>something like this</p>, <br> and etc. Also this is not a web application. If you have any idea how do this. Suggest me. Thanks.

Update

For an example, if I type a text with line breaks, it should automatically insert <br> or <p>. This kind of function is available in Dreamweaver. It automatically inserts the code when you start filling the content in the webpage. The issue is so I don't want the non-technical usres to type the HTML code when they are writing paragraphs, because by default the

tag and all are inserted. I will be emailing this directly to the user after this text is typed, so this formatting is essential.

It is important to note that I don't know what the user will type, it is all upto him. so whatever the method I use should be capable of identfying the places where it could put tags (like paragraph tag) and move on


Solution

  • For an example, if I type a text with line breaks, it should automatically insert <br> or <p>

    The basic requirement would be to use a DocumentFilter to inject your markup when ever they type enter

    Markup

    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.text.AbstractDocument;
    import javax.swing.text.AttributeSet;
    import javax.swing.text.BadLocationException;
    import javax.swing.text.DocumentFilter;
    
    public class TestMarkup {
    
        public static void main(String[] args) {
            new TestMarkup();
        }
    
        public TestMarkup() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public static class TestPane extends JPanel {
    
            public TestPane() {
                setLayout(new BorderLayout());
                JTextArea ta = new JTextArea(10, 20);
                add(new JScrollPane(ta));
    
                ((AbstractDocument) ta.getDocument()).setDocumentFilter(new DocumentFilter() {
    
                    @Override
                    public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
                        if (text.endsWith("\n")) {
                            super.replace(fb, offset, 0, "<br>", attrs);
                            offset += 4;
                        }
                        super.replace(fb, offset, length, text, attrs);
                    }
    
                });
            }
        }
    }
    

    Inserting <p>/</p> "might" be more difficult, but, if you assume that your first line starts with <p>, it's just a matter of inject </p> before the newline and <p> after it, then append the remaining text...

    Updated with Paragraph support and pasting

    Apparently I just can't walk away...

    Markup

    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import java.util.StringJoiner;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.text.AbstractDocument;
    import javax.swing.text.AttributeSet;
    import javax.swing.text.BadLocationException;
    import javax.swing.text.Document;
    import javax.swing.text.DocumentFilter;
    import javax.swing.text.Element;
    
    public class TestMarkup {
    
        public static void main(String[] args) {
            new TestMarkup();
        }
    
        public TestMarkup() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public static class TestPane extends JPanel {
    
            public TestPane() {
                setLayout(new BorderLayout());
                JTextArea ta = new JTextArea(10, 20);
                add(new JScrollPane(ta));
    
                ((AbstractDocument) ta.getDocument()).setDocumentFilter(new DocumentFilter() {
    
                    protected String getLastLineOfText(Document document) throws BadLocationException {
                        // Find the last line of text...
                        Element rootElem = document.getDefaultRootElement();
                        int numLines = rootElem.getElementCount();
                        Element lineElem = rootElem.getElement(numLines - 1);
                        int lineStart = lineElem.getStartOffset();
                        int lineEnd = lineElem.getEndOffset();
                        String lineText = document.getText(lineStart, lineEnd - lineStart);
                        return lineText;
                    }
    
                    @Override
                    public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
                        if (text.length() > 1) {
    
                            String lastLineOfText = getLastLineOfText(fb.getDocument());
                            if (!lastLineOfText.startsWith("<p>")) {
                                if (!text.startsWith("<p>")) {
                                    text = "<p>" + text;
                                }
                            }
    
                            // Replace any line breaks with a new line
                            String[] lines = text.split("\n");
                            if (lines.length > 0) {
    
                                StringJoiner sj = new StringJoiner("<br>\n");
                                for (String line : lines) {
                                    sj.add(line);
                                }
                                text = sj.toString();
    
                            }
    
                            if (!text.endsWith("</p>")) {
                                text += "</p>";
                            }
    
                            super.replace(fb, offset, length, text, attrs);
    
                        } else {
    
                            String postInsert = null;
                            if (text.endsWith("\n")) {
    
                                // Find the last line of text...
                                String lastLineOfText = getLastLineOfText(fb.getDocument());
                                lastLineOfText = lastLineOfText.substring(0, lastLineOfText.length() - 1);
                                postInsert = "<p>";
                                if (!lastLineOfText.endsWith("</p>")) {
    
                                    super.replace(fb, offset, 0, "</p>", attrs);
                                    offset += 4;
                                }
                            }
                            super.replace(fb, offset, length, text, attrs);
                            if (postInsert != null) {
                                offset += text.length();
                                super.replace(fb, offset, 0, "<p>", attrs);
                            }
                        }
                    }
    
                });
            }
        }
    }