I am using MigLayout 3.5.5
, as the newer updates are not compatible with my older code.
Problem
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.
Pattern
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);
}
}
Why am I using 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!