当前位置: 首页 > 面试题库 >

JTextPane / JTextField具有稀有字符的奇怪行为

濮景龙
2023-03-14
问题内容

我在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);
}
}

编辑:这是问题的一个更好的例子。它似乎与字体的大小有关。移动Slider,您将注意到大小14如何不呈现字形,而14恰好是JTextField的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);
}
}

问题答案:

当我尝试制作必须支持多种语言(包括带有“非标准”字符的语言,例如中文)的应用程序时,我遇到了类似的问题。我曾经将我的小部件的字体设置为Arial,并且遇到了问题。以下解决方案解决了我的问题,但可能无法解决您的问题。

每当遇到无法显示的特定字符集的字符时,Java都有一个回退机制。可以使用JRE随附的fontconfig.properties文件进行配置(该文件最初以“
fontconfig.properties.src”的形式提供,您必须手动重命名)。

当你强迫的字体是不中DialogSerifSansSerifMonospaced或者DialogInput,Java有没有办法使用不同的字符集,如果当前一个(在你的情况宋体)不能代表字符(或字形)你想在屏幕上绘制。

如果你看一下fontconfig.properties.src文件,你会看到,是有许多类型的字体(如许多条目Dialog.plainSerif.bold等等)。这些是上述字体无法显示特定字形时将使用的实际后备字体。因此,将小部件的字体设置为例如,Font.DIALOG将允许Java尝试使用字体列表来显示字符。

有关更多信息,请访问Oracle网站(此处为Java
7
)。请注意,Oracle尚未正式支持使用fontconfig.properties。



 类似资料:
  • 我正在编写一个DocumentFilter,它将输入JTextField的所有单词“top”替换为逻辑top符号。 使用此代码很好,但是它很烦人,因为用户必须重新键入他们的空间,他们可以这样做,并且文本继续在同一行上 当用户继续键入文本时,使用此代码并在空格中添加替换符会导致顶部符号和JTextField中的所有文本稍微向上推,然后转到下面并开始一行新的内容 有人能解释一下这种行为,并希望能提供一

  • 问题内容: 我看到了我认为是错误的行为。@InjectMocks似乎并没有在每种测试方法之前创建一个新的测试主题。就像@Mock一样。在下面的示例中,如果Subject.section是最后一个,则@Test失败。如果不是最后两个都通过。我当前的解决方法是使用@BeforeClass,但这并不理想。 Subject.java: Section.java: SubjectTest.java 干杯。

  • 鉴于以下代码: 为什么开关语句在上匹配? 我的理解是,当时,不匹配,因为(实际上)计算结果为false。VS Code上的IntelliSense告诉我,也是一个

  • 问题内容: 在我们的团队中,我们发现在使用和限定词时都有一些奇怪的行为。这是我们的测试课程: 运行该方法时,将得到以下结果: 我会理解它是否两次都写值,因为静态类成员的代码是从上到下执行的。 谁能解释为什么这种现象发生? 问题答案: 这些是您运行程序时采取的步骤: 在可以运行之前,必须按外观顺序通过运行静态初始化程序来初始化该类。 要初始化该字段,请开始执行。 打印的值。由于字段类型为,因此看起来

  • 问题内容: 我有一些奇怪的字符串池行为的问题。我正在使用比较相等的字符串来找出它们是否在池中。 输出为: 这对我来说是一个很大的惊喜。有人可以解释一下吗?我认为这是在编译时发生的。但是,为什么添加到String 根本没有任何区别呢? 问题答案: 是一个编译时常量,而 不是。因此,前者仅编译为字符串常量“ 555”,而后者则编译为实际的方法调用和串联,从而生成一个新的String实例。 另请参见JL

  • 问题内容: 我有一个小文件,其中包含一些我想用“ |”分割的内容 字符。 当我尝试使用其他任何字符(例如“>”)时,它都可以正常工作,但是使用“ |” 性格,有一些意想不到的结果。 行本身(此处带有 >字符) addere> to add>(1) 分割“ >”结果 [加法,加法(1)] 分割“ |” 结果 [,a,d,d,e,r,e,|,t,o,,a,d,d,|,(,1,)] 为什么要拆分所有内容