Radim Burget
Radim Burget

Reputation: 1516

JTextPane - auto wrap inserted JLabel components

I have JTextPane where I have inserted 20 components (JLabels). Unfortunately all the labels are on a single line.

How can I enforce that the JTextPane will automatically wrap the inserted objects?

enter image description here

package texteditor;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;

public class JTextPaneExample extends JPanel {

    private JTextPane tp;

    public JTextPaneExample() {
        setLayout(new BorderLayout(0, 0));

        JPanel panel = new JPanel();
        add(panel, BorderLayout.CENTER);
        panel.setLayout(new BorderLayout(0, 0));

        JScrollPane scrollPane = new JScrollPane();
        panel.add(scrollPane, BorderLayout.CENTER);

        tp = new JTextPane();
        tp.setEditable(false);
        scrollPane.setViewportView(tp);

        for (int i = 0; i < 20; i++) {
            JLabel lbl = new JLabel("AAAA ");
            lbl.setOpaque(true);
            lbl.setBorder(BorderFactory.createLineBorder(Color.black, 1));
            tp.insertComponent(lbl);
        }
    }


    public static void main(String[] args) {
        JFrame frame = new JFrame("GoBoard");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new JTextPaneExample());
        frame.setPreferredSize(new Dimension(400, 400));
        frame.pack();
        frame.setVisible(true);
    }
}

Upvotes: 1

Views: 443

Answers (2)

camickr
camickr

Reputation: 324108

A JTextPane wraps on spaces. Your Document doesn't have any spaces so there is nothing to wrap on. You can add a space between labels:

for (int i = 0; i < 20; i++) {
    JLabel lbl = new JLabel("AAAA ");
    lbl.setOpaque(true);
    lbl.setBorder(BorderFactory.createLineBorder(Color.black, 1));
    tp.insertComponent(lbl);
    doc.insertString(doc.getLength(), " ", null);
    tp.setCaretPosition(doc.getLength());
}

Also, still not sure why you are using a JTextPane for this. You can just use a JPanel and have the components on the panel wrap to the next line. See Wrap Layout for a solution using this approach.

This should also make the solution from your last question (JTextPane - get component values) easier since you will be dealing with real components you won't need to search the Document to get the clicked label.

Upvotes: 2

ControlAltDel
ControlAltDel

Reputation: 35011

you need to use a LayoutManager, and in this case, you may want to / have to build your own LayoutManager (I had to do this for a similar problem years ago). In your LayoutManager layoutComponent method, check the index of the label and the length of all preferredsize.width / size.width of all components before that. If this is greater than your JTextPane preferredsize.width / size.width, move it to the next line.

Upvotes: 1

Related Questions