How to wrap text around components in a JTextPane?
Asked Answered
M

1

5

I don't understand the wrapping behavior in a JTextPane. If I insert a short text, then a JComponent and then again the short text I can see the inserted stuff in one line if the frame is large enough of course. But if the text is much longer so that it takes several lines the component is always placed in a new line.

I have recognized that after a component has been inserted into a JTextPane its text gets longer by one character. So if a component is considered by a JTextPane as a character why doesn't it behave like a character? May it depend on the java version? I use Java(TM) SE Runtime Environment (build 1.7.0-b147)

Below is my code (instantiate the variable currentText with shortText/longText to reproduce the mentioned behavior):

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;

public class Test {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JTextPane textPane = new JTextPane();
        textPane.setContentType("text/html");

        String shortText = "one two three four five six seven";
        String longText = "A text component that can be marked up with attributes that are represented graphically. You can find how-to information and examples of using text panes in Using Text Components, a section in The Java Tutorial. This component models paragraphs that are composed of runs of character level attributes. Each paragraph may have a logical style attached to it which contains the default attributes to use if not overridden by attributes set on the paragraph or character run. Components and images may be embedded in the flow of text.";
        String currentText = shortText;

        try {
            // insert text before the component
            textPane.getDocument().insertString(textPane.getDocument().getLength(), currentText,
                    new SimpleAttributeSet());

            textPane.setSelectionStart(textPane.getDocument().getLength());
            textPane.setSelectionEnd(textPane.getDocument().getLength());

            JComboBox component = new JComboBox();
            component.setMaximumSize(component.getPreferredSize());
            textPane.insertComponent(component);

            // insert text after the component
            textPane.getDocument().insertString(textPane.getDocument().getLength(), currentText,
                    new SimpleAttributeSet());

        } catch (BadLocationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        textPane.setEditable(false);

        frame.add(new JScrollPane(textPane));
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}
Mcclure answered 27/8, 2012 at 10:13 Comment(0)
M
3

That strange behavior seems to happen due to the content type you set. Try removing this line:

textPane.setContentType ( "text/html" );

and you will see that everything works fine after that. I am not sure why it happens - might be either some rendering bug or just an intended behavior.

P.S. I don't think that using Swing components inside text pane (whatever the reason is) is a good option. But that is just my opinion...

Mcnary answered 27/8, 2012 at 11:20 Comment(2)
Yes, it works. Why do you think it is not a good idea to use a JTextPane? I want to create a program for doing exercises. The exercises must contain combo boxes and text fields. The user must also be able to "underline" (select) the text. How to do it in other way? Use JLabels or disabled JTextFields? You cannot select their text, can you? Even if you can I thought that it wouldn't be good to add so many of these elements each time you have a text piece.Mcclure
@Mcclure well, that might be one of few cases when its the easiest way to do things :)Mcnary

© 2022 - 2024 — McMap. All rights reserved.