n00*_*ter 5 java swing jtextpane jtextfield
我在JTextPane/JTextField中发现了一个奇怪的错误(或者在它们下面的字体渲染中的某个地方).我想知道是否有其他人遇到过这种情况并且可能有解决方案.
我试图在JTextPane中显示一些"特殊"或罕见的字符,并且一旦我更改了JTextField的字体(与JTextPane完全无关!),JTextPane就会"分解",并且不再显示这些字符字符.
这应该更好地解释我的意思:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:这是问题的一个更好的例子.它似乎与Font的大小有关.移动滑块,您会注意到大小14不会渲染字形,而14恰好是JTextField字体的大小.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试制作一个必须支持多种语言(包括具有“非标准”字符的语言,例如中文)的应用程序时,我遇到了类似的问题。我曾经将小部件的字体设置为Arial,但遇到了问题。以下解决方案解决了我的问题,但可能无法解决您的问题。
当 Java 遇到无法显示的特定字符集中的字符时,它有一个后备机制。它可以使用 JRE 提供的 fontconfig.properties 文件进行配置(该文件最初提供为“fontconfig.properties.src”,您必须手动重命名它)。
当您强制使用不在Dialog、Serif、SansSerif或Monospaced之间DialogInput的字体时,如果当前字符集(在您的情况下为 Arial)无法表示您尝试在屏幕上绘制的字符(或字形),则 Java 无法使用其他字符集。
如果您查看 fontconfig.properties.src 文件,您将看到它有许多针对多种类型字体的条目(例如Dialog.plain、Serif.bold等)。当上面的字体无法显示特定字形时,这些是实际使用的后备字体。因此,将小部件的字体设置为Font.DIALOG允许 Java 尝试使用字体列表来显示字符。
更多信息请访问 Oracle 网站(此处针对 Java 7)。请注意,Oracle 不正式支持使用 fontconfig.properties。