Java - 如何在 JTextPane 中正确显示 ANSI 艺术

标签 java user-interface fonts jtextpane

我无法显示 ANSI artJTextPane 中。

我认为简单地选择固定宽度或等宽字体并通过 SimpleAttributeSet 删除 JTextPaneStyledDocument 的行距会足以正确显示 some different pieces of ANSI art ,但在尝试不同的字体和设置后,我意识到它必须不止于此。

我一直在使用 DAMN NFO Viewer比较我的 JTextPane 以查看我的代码是否显示 the piece of digital art正确。

我通过 artTextPane 将 JTextPane 字体设置为 DAMN NFO Viewer 使用的相同字体(根据其设置Courier New,8,默认情况下)。 setFont(new java.awt.Font("Courier New", 0, 8)).但是,即使我通过 StyledDocument.setParagraphAttributes(int, int, AttributeSet, boolean) 应用行间距设置,我的 JTextPane 也无法正确显示艺术作品。 这是两个显示差异的屏幕截图:

该死的 NFO 查看器(Courier New,8):

DAMN NFO Viewer Courier New 8

我的JTextPane(Courier New 8):

JTextPane Courier New 8

真正奇怪的是,当我将 JTextPane 的字体大小设置为 9 时,对齐方式似乎是正确的,但有点不清晰。放大艺术作品中构成 g 的字符会在右侧显示蓝色像素,使其看起来不清晰:

我的JTextPane(Courier New 9):

JTextPane Courier New 9

我还注意到打开 art.txt在记事本中显示它就像 DAMN NFO Viewer 一样。此外,JTextPane 似乎显示得更小,例如,绘制字符的“棺材”看起来更小。

首先我以为该死的 NFO Viewer 使用了不同版本的字体 Courier New,所以我翻遍了它的目录并找到了以下注册表文件:

[HKEY_CURRENT_USER\Software\DAMN\DAMN NFO Viewer\NFO]
"FontName"="[built-in] Courier New"
"FontData"=hex:91,00,03,01
"Window"=dword:00000023
"BackgroundColor"=hex:ff,ff,ff,00
"TextColor"=hex:00,00,00,00
"HyperLinkColor"=hex:bf,cd,db,00
"HyperLinkHoverColor"=hex:99,b4,d1,00
"Text"=dword:00000400

这让我觉得它可能使用 Courier New 的派生版本,设置 "FontData"=hex:91,00,03,01。但是我不知道如何在 Java 中重现该推导。

谁能告诉我我在尝试以 DAMN NFO Viewer 相同的方式在 JTextPane 中显示文本文件时做错了什么?

编辑: 添加了一些我目前正在使用的测试/示例代码,试图让字体“正确”显示(以不破坏 ANSI 艺术的方式)。我使用 NetBeans IDE 创建了这个测试 GUI的内置 GUI 构建器“Mantisse”,因此它可能不是一个完美的示例,但它应该清楚地显示与 DAMN NFO Viewer 的屏幕截图的区别。

package jtextpanetest;

public class JTextPaneTestUI extends javax.swing.JFrame {

/**
 * Creates new form JTextPaneTestUI
 */
public JTextPaneTestUI() {
    initComponents();
}

/**
 * This method is called from within the constructor to initialize the form.
 * WARNING: Do NOT modify this code. The content of this method is always
 * regenerated by the Form Editor.
 */
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    scrollPane = new javax.swing.JScrollPane();
    panel = new javax.swing.JPanel();
    textPanesSrollPane = new javax.swing.JScrollPane();
    textPane = new javax.swing.JTextPane();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    panel.setLayout(new java.awt.BorderLayout());

    textPane.setFont(new java.awt.Font("Courier New", 0, 8)); // NOI18N
    textPane.setText("▀▀▀▀▀▀▀▀▀▄▄▄▄\n███████▄▄▄▄ ▀▀▀▄▄\n▄ ▀█▓█████████▄▄ ▀▀█▄\n █  ▓█▓▄ ▀▀█▓███▓▄  ██\n  █ ▒▓▒▓    ▒█▓█▒▓  █▓█\n  █ ░▒░▒█ █ ░▓▒▓░▒█ █▒▓█\n  █ ░░░░▓ █ ░▒░▒░░▓ ▓░▒█\n  █ ▒░▒░▒ █ ▒░░░▒░▒ ▒░░█\n  █ ▓▒▓▒░ █ ▓░▒░▓▒░ ░▒░█\n  █ █▓█▓▀ █ █▒▓▒█▓░ ░▓▒█\n  █ ██▀ ▄▀█ █▓█▓██  ▒██\n  █ █ ▄▀▄█  █████▀  ▓█\n  ░ █ ░ █ ▄██▀▀ ▄▄█ █░\n  ▒▄▄▄▒ ░▄▄▄▄▄▀▀  █ █\n          █ ██▀ ▄▀                   \n          █ █▌▄▀  \n          ░ █ █                  \n          ▒▄▄▄░ \n\n █████████\n███████████\n███████████\n███████████\n█████ █████\n█████ █████\n█████ █████\n█████ █████\n█████ █████\n███████████\n███████████\n ██████████\n     ██████\n███████████\n██████████      ");
    textPanesSrollPane.setViewportView(textPane);

    panel.add(textPanesSrollPane, java.awt.BorderLayout.CENTER);

    scrollPane.setViewportView(panel);

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
    );

    pack();
}// </editor-fold>                        

/**
 * @param args the command line arguments
 */
public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(JTextPaneTestUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            new JTextPaneTestUI().setVisible(true);
        }
    });
}


private javax.swing.JPanel panel;
private javax.swing.JScrollPane scrollPane;
private javax.swing.JTextPane textPane;
private javax.swing.JScrollPane textPanesSrollPane;

}

编辑 2: 有人建议我将艺术作品渲染为图像,但我需要它是可编辑的,所以我猜这不是一个选项。任何提示表示赞赏!

最佳答案

此处的主要问题是 JTextPane 中的文本在呈现时行间距太大。其他小部件也会出现同样的问题。实际间距取决于字体(因此也取决于 JVM)。您在 Courier 9 中观察到的蓝色模糊可能是由抗锯齿引起的。

您的代码在 MacOS X 上使用 Java 1.7.0_55-b13 呈现如下: Original rendering

使用 JTextPane,您可以按如下方式减小行间距(在调用 JTextPane.setText 之前):

javax.swing.text.MutableAttributeSet set = new javax.swing.text.SimpleAttributeSet(textPane.getParagraphAttributes());
javax.swing.text.StyleConstants.setLineSpacing(set, (float)-0.1);
textPane.setParagraphAttributes(set, false);

-0.1 值修复了行间距,您可能需要其他字体或字体大小的其他值。

Removed space between lines

您可能还需要减少跟踪(字母之间的空间):

java.awt.Font font = new java.awt.Font("Courier New", 0, 8);
java.util.Map<java.awt.font.TextAttribute, Object> attributes = new java.util.HashMap<java.awt.font.TextAttribute, Object>();
attributes.put(java.awt.font.TextAttribute.TRACKING, -0.1);
java.awt.Font font2 = font.deriveFont(attributes);
textPane.setFont(font2);

Rendering with tracking

关于Java - 如何在 JTextPane 中正确显示 ANSI 艺术,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23715048/

相关文章:

ios - iOS 中具有大小等级的自定义字体

css - google webfonts 在 chrome 上看起来很糟糕

java - Android 比较背景颜色和颜色

java - 使用操作栏发送数据 [Android]

visual-studio - Visual Studio 2013 中的默认字体是什么

java - 从 Swing GUI 编译和运行 Java 代码

jQuery UI Accordion 锁定某些元素

java - Spring 测试因 NoClassDefFoundError 失败

java - 加载 hibernate 实体时始终调用方法

eclipse - 如何隐藏/禁用 CDT 启动栏?