【问题标题】:Swing text looks badSwing 文本看起来很糟糕
【发布时间】:2012-07-14 18:21:28
【问题描述】:

我正在重写 JCOmponent 的 paintComponent() 方法并在窗口中绘制文本。我在 Ubuntu 上运行并使用字体“Ubuntu Mono”(Ubuntu 文本编辑器的默认字体)。当我的 java 应用程序显示文本时,它看起来很软弱和模糊。我做错了什么?

我正在画这样的文字:

graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
Font font = new Font("Ubuntu Mono", Font.PLAIN, 18);
fontMetrics = graphics.getFontMetrics(font);
graphics.setFont(font);
graphics.drawString(value, getX(), getY() + fontMetrics.getHeight());

在我的 java 应用程序中,它看起来像这样:

在 Ubuntu 文本编辑器中,它看起来像这样:

编辑:如果使用.png 图像而不是drawText(),性能会受到影响吗?这是一个商业应用程序,而不是一个需要流畅动画的游戏。

编辑:我更改了颜色以匹配 TextEditor 的颜色,这实际上对质量有所帮助,但字符仍然很薄……你几乎看不到“.”。在 gimp 中,我可以通过创建带有正确字体和抗锯齿功能的文本来重新创建 TextEditor 外观。

【问题讨论】:

  • 我感觉也许 Java(或者 Swing)没有我需要的那么多控制。我更改了 netbeans 中的字体(使用 swing)以匹配我的应用程序的字体,它看起来一样。 groan 我在这个项目中没有时间学习C++?看起来所有主要的浏览器都是用 C++ 编写的。有什么想法吗?
  • 这个LayoutTest 使用TextLayout 可能有用。
  • 这可能是一个分辨率问题。我记得(我查这些东西已经有一段时间了),Java 以 72 DPI 运行(或者是 92 DPI??)

标签: java swing fonts antialiasing


【解决方案1】:

奇怪的是,我尝试使用“Monospaced”而不是“Ubuntu Mono”:

graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

它看起来对我来说已经足够好了。这就是我要使用的。

【讨论】:

  • 谢谢你,这让我很惊讶
【解决方案2】:

读取 .png 图像并将其缓存到 BufferedImage。性能不会受到影响 - 实际上使用这样的中间图像比首先绘制文本具有更好的性能。

确保将其设为兼容的图像,如下所示:

private Image getCompatibleImage(BufferedImage img) throws IOException {
        GraphicsConfiguration c = GraphicsEnvironment
                .getLocalGraphicsEnvironment().getDefaultScreenDevice()
                .getDefaultConfiguration();

        if (c.getColorModel().equals(img.getColorModel()))
            return img;

        BufferedImage compatible = c.createCompatibleImage(img.getWidth(),
                img.getHeight());
        Graphics cg = compatible.getGraphics();
        cg.drawImage(img, 0, 0, null);
        cg.dispose();

        return compatible;
    }

这将在某些显示器上节省每像素转换以提高性能。

【讨论】:

    【解决方案3】:

    你不一定做错了什么。来自RenderingHints 的 API(强调我的):

    这些键和值是提示,不要求给定的实现支持下面指出的所有可能的选择,或者它可以响应修改其算法选择的请求。提示键也可以交互,这样虽然在一种情况下支持给定键的所有变体,但当修改与其他键关联的值时,实现可能会受到更多限制。 [剪辑]

    实现可以完全忽略提示,但应尝试使用尽可能接近请求的实现算法。

    【讨论】:

      【解决方案4】:

      不要强制渲染提示,而是尝试使用本机桌面设置来设置字体,即:

      Toolkit tk = Toolkit.getDefaultToolkit();
      Map desktopHints = (Map)(tk.getDesktopProperty("awt.font.desktophints"));
      
      ...
      
      if (desktopHints != null) {
          graphics.addRenderingHints(desktopHints);
      }
      

      (来源 - Filthy Rich Clients)

      编辑:

      请务必尝试各种控制文本渲染质量的提示。这是reference 和examples。

      【讨论】:

      • 嗯...略有变化,但仍然比 TextEditor 字体差很多。
      • @Stinky 你尝试过 GASP 或 LCD 提示吗?
      • @Max 我做到了。它们看起来与 VALUE_TEXT_ANTIALIAS_ON 非常相似。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-29
      • 2012-12-03
      • 2014-04-09
      • 2017-08-29
      • 1970-01-01
      相关资源
      最近更新 更多