I've discovered a strange bug in JTextPane/JTextField (or somewhere in the font rendering underneath them). I wonder if anyone else has encountered the same and might have a solution for this.
I'm trying to display some "special" or rare characters in a JTextPane, and as soon as I change the font of the JTextField (which is completely unrelated to JTextPane!), the JTextPane "breaks up", and no longer displays these characters.
This should do a better job explaining what I mean:
public class Scrap {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(200, 200);
frame.setLayout(new BorderLayout());
JTextField field = new JTextField();
// Uncomment this line... and the JTextPane nor the JTextField
// no longer display the characters
// field.setFont(new Font("Arial", Font.PLAIN, 14));
frame.add(field, BorderLayout.SOUTH);
JTextPane textPane = new JTextPane();
textPane.setFont(new Font("Arial", Font.PLAIN, 14));
JScrollPane scroll = new JScrollPane(textPane);
frame.add(scroll, BorderLayout.CENTER);
StyledDocument doc = (StyledDocument) textPane.getDocument();
try {
String str = "? ?? ?";
doc.insertString(doc.getLength(), str, null);
} catch (BadLocationException e) {
e.printStackTrace();
}
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
}
EDIT: Here's a better example of the problem. It appears to be related to the size of the Font. Move the Slider and you'll notice how the size 14 does not render the glyphs, and 14 happens to be the size of the JTextField's Font.
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.*;
import java.awt.*;
public class Scrap {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 200);
frame.setLayout(new BorderLayout());
final JTextField field = new JTextField(10);
final JTextPane textPane = new JTextPane();
StyledDocument doc = (StyledDocument) textPane.getDocument();
JPanel panel = new JPanel();
frame.add(panel, BorderLayout.SOUTH);
// Set the Font of the JTextField, and the JTextPane
// no longer displays the text of that size correctly...
int changeMe = 14;
field.setFont(new Font("Tahoma", Font.PLAIN, changeMe));
// If we change the Font Family, the problem goes away...
// field.setFont(new Font("Dialog", Font.PLAIN, 14));
panel.add(field);
final JLabel label = new JLabel();
final JSlider slider = new JSlider(6, 32);
slider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
textPane.setFont(new Font("Tahoma", Font.PLAIN, slider.getValue()));
textPane.selectAll();
SimpleAttributeSet attr = new SimpleAttributeSet();
StyleConstants.setFontSize(attr, slider.getValue());
textPane.setCharacterAttributes(attr, true);
label.setText("" + slider.getValue());
}
});
slider.setValue(14);
panel.add(slider);
panel.add(label);
JScrollPane scroll = new JScrollPane(textPane);
frame.add(scroll, BorderLayout.CENTER);
Style s = doc.addStyle("test", null);
try {
String str = "? ?? ?";
doc.insertString(doc.getLength(), str, doc.getStyle("test"));
} catch (BadLocationException e) {
e.printStackTrace();
}
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
}
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…