I am using MigLayout 3.5.5
, as the newer updates are not compatible with my older code.
When setting text to a JTextPane
in a MigLayout
, the JTextPane
will take double the space (according to font size) IF the text I am setting the JTextPane
contains space characters. It does not happen all the time, but in the specific program I am making, it happens frequently.
The program's goal is to present information in a letter-by-letter basis, so there is a button that updates the text to the next letter. However, the text bounces around, because the JTextPane
is sometimes occupying more space than usual. I identified a certain pattern to the height differences.
A new line indicates that I added a letter.
"|" represents a space character in the text.
"Space" means JTextPane
is taking double the space.
Full String: "The quick brown fox jumps over the lazy dog."
T
Th
The
The|
The|q (Space)
The|qu
The|qui (Space)
The|quic
The|quick (Space)
The|quick|
Note: I stopped the pattern here, because from this point on (starting with The|quick|b), every single letter addition resulted in the JTextPane
occupying double its height.
I've already tried printing out the letter-by-letter text to the console to see if there were any new line characters within the text being added, but to no avail. I also thought it might be a problem with the automatic wrapping of the JTextPane
, but the text I inserted isn't quite long enough to wrap in the JFrame
's size.
Here is a short example to reproduce the behavior:
public class MainFrame extends JFrame {
int currentLetter = 1;
final String FULL_TEXT = "The quick brown fox jumps over the lazy dog.";
JTextPane text;
JButton addLetter;
MainFrame() {
setSize(500, 500);
setLayout(new MigLayout("align center, ins 0, gap 0"));
addElements();
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
MainFrame application = new MainFrame();
}
});
}
private void addElements() {
text = new JTextPane();
text.setEditable(false);
text.setFont(new Font("Times New Roman", Font.BOLD, 19));
text.setForeground(Color.WHITE);
text.setBackground(Color.BLACK);
add(text, "alignx center, wmax 80%, gapbottom 5%");
addLetter = new JButton("Add Letter");
addLetter.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (currentLetter != FULL_TEXT.length()) {
currentLetter++;
updateText();
}
}
});
add(addLetter, "newline, alignx center");
updateText();
}
private void updateText() {
String partialText = new String();
for (int letter = 0; letter < currentLetter; letter++) {
partialText += FULL_TEXT.toCharArray()[letter];
}
text.setText(partialText);
}
}
JTextPane
?I tried using JLabel
for this task, and it worked well... until the text was long enough to wrap. Then, when I used HTML within the JLabel
text to wrap it, every time I updated the text, it would take time for the HTML to render and result in some pretty nasty visual effects.
Next, I tried JTextArea
to disguise it as a JLabel
, since it not only has line wrapping, but word wrapping as well. It was a great solution, until I found out that I couldn't use a center paragraph alignment in a JTextArea
.
So I settled for a JTextPane
, which will work well if only I got rid of the extra space at the bottom of it.
Thanks in advance for your help!
The solution is to append text by using the insertString() method on the StyledDocument of the JTextPane instead of using setText() on the JTextPane itself.
For example, instead doing this every time:
JTextPane panel = new JTextPane();
panel.setText(panel.getText() + "test");
You should do this:
JTextPane panel = new JTextPane();
StyledDocument document = panel.getStyledDocument();
document.insertString(document.getLength(), "test", null);
And of course you need to catch the BadLocationException.
Then the space disappears. Here's the question where I found my answer to the rendering problem: JTextPane appending a new string
The answers to those questions don't address the problem with the space, but they do show the correct way to edit text in the JTextPane.