So I'm building a chat GUI in java, and I tried to use JTextPane with StyleConstants et SimpleAttributeSet. The result I got is almost 100% what I want, I only got 1 minor issue.
So here is what I got for now :

The thing is, with small text, the result is pretty good looking, but with longer text, the blue (or gray) message extends too much and they arrive at the same place the other color begin.
So, I want to "delete" the red parts, and by deleting I mean forcing this to be one line below and have a blank space where the red parts are.
What I want is more like this :

As you can see, even with long text, there is a small difference between where the blue text extends and where the gray text begin. And I'll like to "force" that, with something like a maximum width or something but I can't find how.
Here is the code to reproduce this :
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ComponentOrientation;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
public class MainGUI {
String appName = "Colt Chat v0.1";
MainGUI mainGUI;
JFrame newFrame = new JFrame(appName);
JButton sendMessage;
JTextField messageBox;
JTextPane chatBox;
JTextField usernameChooser;
JFrame preFrame;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager
.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
MainGUI mainGUI = new MainGUI();
mainGUI.display();
}
});
}
public void display() {
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
JPanel southPanel = new JPanel();
southPanel.setBackground(Color.BLUE);
southPanel.setLayout(new GridBagLayout());
messageBox = new JTextField(30);
messageBox.requestFocusInWindow();
sendMessage = new JButton("Send Message");
sendMessage.addActionListener(new sendMessageButtonListener());
chatBox = new JTextPane();
chatBox.setEditable(false);
chatBox.setFont(new Font("Serif", Font.PLAIN, 15)) ;
//chatBox.setLineWrap(true);
JScrollPane scrollPane = new JScrollPane(chatBox);
mainPanel.add(scrollPane, BorderLayout.CENTER);
textPane = new JTextPane();
scrollPane.setRowHeaderView(textPane);
GridBagConstraints left = new GridBagConstraints();
left.insets = new Insets(0, 0, 0, 5);
left.gridx = 0;
left.gridy = 0;
left.anchor = GridBagConstraints.LINE_START;
left.fill = GridBagConstraints.HORIZONTAL;
left.weightx = 512.0D;
left.weighty = 1.0D;
GridBagConstraints right = new GridBagConstraints();
right.gridx = 2;
right.gridy = 0;
right.insets = new Insets(0, 10, 0, 0);
right.anchor = GridBagConstraints.LINE_END;
right.fill = GridBagConstraints.NONE;
right.weightx = 1.0D;
right.weighty = 1.0D;
southPanel.add(messageBox, left);
btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new sendMessageButtonListener2());
GridBagConstraints gbc_btnNewButton = new GridBagConstraints();
gbc_btnNewButton.insets = new Insets(0, 0, 0, 5);
gbc_btnNewButton.gridx = 1;
gbc_btnNewButton.gridy = 0;
southPanel.add(btnNewButton, gbc_btnNewButton);
southPanel.add(sendMessage, right);
mainPanel.add(BorderLayout.SOUTH, southPanel);
newFrame.getContentPane().add(mainPanel);
newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
newFrame.setSize(470, 300);
newFrame.setVisible(true);
}
class sendMessageButtonListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
StyledDocument doc = chatBox.getStyledDocument();
SimpleAttributeSet rightO = new SimpleAttributeSet();
StyleConstants.setAlignment(rightO, StyleConstants.ALIGN_RIGHT);
StyleConstants.setBackground(rightO, Color.RED);
StyleConstants.setBackground(rightO, new Color(59,130,247));
StyleConstants.setForeground(rightO, new Color(255,255,255));
StyleConstants.setRightIndent(rightO, 10);
if (messageBox.getText().length() < 1) {
// do nothing
} else if (messageBox.getText().equals(".clear")) {
chatBox.setText("Cleared all messages\n");
messageBox.setText("");
} else {
//chatBox.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
//chatBox.append("<" + username + ">: " + messageBox.getText() + "\n");
try {
int length = doc.getLength();
chatBox.getDocument().insertString(doc.getLength(), "\n\n"+messageBox.getText(), rightO);
chatBox.setParagraphAttributes(rightO, false);
} catch (BadLocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
messageBox.setText("");
}
messageBox.requestFocusInWindow();
}
}
class sendMessageButtonListener2 implements ActionListener {
public void actionPerformed(ActionEvent event) {
StyledDocument doc = chatBox.getStyledDocument();
SimpleAttributeSet leftO = new SimpleAttributeSet();
StyleConstants.setAlignment(leftO, StyleConstants.ALIGN_LEFT);
StyleConstants.setBackground(leftO, new Color(60,60,60));
StyleConstants.setForeground(leftO, new Color(255,255,255));
StyleConstants.setLeftIndent(leftO, 10);
if (messageBox.getText().length() < 1) {
// do nothing
} else if (messageBox.getText().equals(".clear")) {
chatBox.setText("Cleared all messages\n");
messageBox.setText("");
} else {
//chatBox.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
//chatBox.append("<" + username + ">: " + messageBox.getText() + "\n");
try {
int length = doc.getLength();
chatBox.getDocument().insertString(doc.getLength(), "\n\n"+messageBox.getText(), leftO);
chatBox.setParagraphAttributes(leftO, false);
} catch (BadLocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
messageBox.setText("");
}
messageBox.requestFocusInWindow();
}
}
String username;
private JButton btnNewButton;
private JTextPane textPane;
class enterServerButtonListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
username = usernameChooser.getText();
if (username.length() < 1) {
System.out.println("No!");
} else {
preFrame.setVisible(false);
display();
}
}
}
}

Well, after some research, I had the solution in front of my eyes all this time, the only thing I needed to do was to add left indent to the message that start at the right of the screen and right indent to the message that start at the left of the screen. Here is the example :