0

I have a swing gui with a JTextPane to output the log from the underlying application. My problem is that after init the gui and log the first log entries the scrollbar is "disabled" until i trigger an action. After the next log entries the horizontal scroller "appears".

The second problem is that sometimes it happens that a log statement is 1030 chars long. But the horizontal scrolling is max for 606 chars. If i copy the text from the JTextPane I got the hole (1030char) text.

I tried in the MainFrame to logTxtArea.setText(" ... -> 1030 chars..."); <<- the scroller works as expected and also the log statements are displayed.

Here is my JTestPane init code in the Mainframe

private static JTextPane logTxtArea = new JTextPane();
......

        logTxtArea.setEditable(false);
        logTxtArea.setEditorKit(new NoWrapEditorKit());
        JScrollPane logScroller = new JScrollPane(logTxtArea);
        logScroller.setFont(new Font("Segoe UI", Font.PLAIN, 12));
        logScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        logScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
        gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.SOUTHWEST;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.gridwidth = 1;
        gbc.gridheight = 8;
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.insets = new Insets(10, 15, 10, 5);
        gbc.weightx = 1;
        gbc.weighty = 1;
        main.add(logScroller, gbc);

And my NoWrapEditorKit ->

public class TextAreaAppender extends AppenderSkeleton {

    private static Style style;

    protected void append(LoggingEvent event) {
        this.layout = new PatternLayout("%d - %m%n");
        String msg = this.layout.format(event);
        JTextPane textArea = MainFrame.getLogTxtArea();
        Color color = Color.BLACK;

        if (event.getLevel() == Level.INFO) {
            color = Color.BLUE;
        } else if (event.getLevel() == Level.WARN || event.getLevel() == Level.ERROR || event.getLevel() == Level.FATAL) {
            color = Color.RED;
        }

        if (msg.contains("INFO:")) {
            color = Color.MAGENTA;
        }

        appendToPane(textArea, msg, color);
        MainFrame.getLogTxtArea().setCaretPosition(MainFrame.getLogTxtArea().getDocument().getLength());
    }

    public void close() {
    }

    public boolean requiresLayout() {
        return false;
    }

    private void appendToPane(JTextPane tp, String msg, Color c) {
        int len = tp.getDocument().getLength();
        if (style == null) {
            style = tp.addStyle("", null);
        }

        try {
            StyleConstants.setForeground(style, c);
            tp.getStyledDocument().insertString(len, msg, style);
        } catch (BadLocationException e) {
            e.printStackTrace();
        }
    }
}

So the target is to get a log statement per line without line break. Also the very long statements (1030 chars) should displayed complete.

Thx!

UPDATE

Here is a short example:

public class TextFrame extends JFrame {

    private JTextPane txtPane;
    private Style style;

    public TextFrame() {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setResizable(true);
        this.setMinimumSize(new Dimension(600, 400));
        this.setPreferredSize(new Dimension(900, 600));

        txtPane = new JTextPane()
        {
            public boolean getScrollableTracksViewportWidth()
            {
                return getUI().getPreferredSize(this).width
                        <= getParent().getSize().width;
            }
        };
        txtPane.setEditable(false);
        JScrollPane logScroller = new JScrollPane(txtPane);
        logScroller.setFont(new Font("Segoe UI", Font.PLAIN, 12));
        logScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        logScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
        this.add(logScroller);

        append("Short text" + System.lineSeparator(), Color.BLACK);
        append("1030 char text - 1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz12345"  + System.lineSeparator(), Color.BLACK);
        append("2000 char text - 1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz123"  + System.lineSeparator(), Color.BLACK);

        this.pack();
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }

    private void append(String message, Color color) {

        int len = txtPane.getDocument().getLength();
        if (style == null) {
            style = txtPane.addStyle("", null);
        }

        try {
            StyleConstants.setForeground(style, color);
            txtPane.getStyledDocument().insertString(len, message, style);
        } catch (BadLocationException e) {
            e.printStackTrace();
        }

        //scroll to bottom
        txtPane.setCaretPosition(txtPane.getDocument().getLength());
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (UnsupportedLookAndFeelException e) {
                    e.printStackTrace();
                }
                new TextFrame();
            }
        });
    }

}
typhon
  • 73
  • 1
  • 1
  • 7
  • *And my NoWrapEditorKit* - I don't see any code. Post your [mre] demonstrating the problem. So we should be able to copy/paste/compile/test the code. The code should be in a single class. You can also check out: [No Wrap Text Pane](https://tips4java.wordpress.com/2009/01/25/no-wrap-text-pane/) for approaches to keep the text in a JTextPane from wrapping. – camickr Apr 22 '20 at 20:54
  • Hi, sorry - please see the update in my original post with a working sample and your suggestion. Now the complete message is displayed but with a linebreak and also the Font setting is not working? – typhon Apr 23 '20 at 06:40
  • 1
    1) the font should be set on the text pane, not the scroll pane 2) There are wrapping issues with the JTextPane. It appears that that at a certain width wrapping is forced. There are other discussions in the forum complaining that text doesn't wrap. This may be somehow related. Check out: https://stackoverflow.com/questions/8666727/wrap-long-words-in-jtextpane-java-7 and https://stackoverflow.com/questions/7036543/how-is-word-wrapping-implemented-in-jtextpane-and-how-do-i-make-it-wrap-a-strin. Fixing this problem is above my knowledge level. – camickr Apr 23 '20 at 15:30

1 Answers1

0

got it working.. The solution is to add the JTextPane to a JPanel. Set the Layout of the JPanel to BoarderLayout. I recognize that the scroll speed stucks so I set the scroll speed.

Here is the final solution:

public class TextFrame extends JFrame {

    private JTextPane txtPane = new JTextPane();
    private Style style;

    public TextFrame() {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setResizable(true);
        this.setMinimumSize(new Dimension(600, 400));
        this.setPreferredSize(new Dimension(900, 600));


        txtPane.setFont(new Font("Segoe UI", Font.PLAIN, 20));
        txtPane.setEditable(false);

        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        panel.add(txtPane);

        JScrollPane logScroller = new JScrollPane(panel);
        logScroller.getVerticalScrollBar().setUnitIncrement(16);
        logScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        logScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
        this.add(logScroller);

        //txtPane.setText("TEST text in this line..");
        append("Short text" + System.lineSeparator(), Color.BLACK);
        append("1030 char text - 1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz12345"  + System.lineSeparator(), Color.BLACK);
        append("2000 char text - 1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz123"  + System.lineSeparator(), Color.BLACK);

        this.pack();
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }

    private void append(String message, Color color) {

        int len = txtPane.getDocument().getLength();
        if (style == null) {
            style = txtPane.addStyle("", null);
        }

        try {
            StyleConstants.setForeground(style, color);
            txtPane.getStyledDocument().insertString(len, message, style);
        } catch (BadLocationException e) {
            e.printStackTrace();
        }

        //scroll to bottom
        //txtPane.setCaretPosition(txtPane.getDocument().getLength());
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (UnsupportedLookAndFeelException e) {
                    e.printStackTrace();
                }
                new TextFrame();
            }
        });
    }

}
typhon
  • 73
  • 1
  • 1
  • 7