【问题标题】:Alloy Look and Feel and Anti-Aliasing合金外观和抗锯齿
【发布时间】:2013-01-17 16:55:52
【问题描述】:

这里有人使用合金外观吗?我正面临一个带有抗锯齿和 JTextComponents 的奇怪错误。 Alloy 默认情况下根本不使用抗锯齿,所以我必须通过创建自己的 UI 类来强制它。这在大多数情况下都可以正常工作,但某些字符会对抗锯齿造成严重破坏。

例如,如果 Alloy 设置为外观,并且我将一些希伯来语文本插入到 JTextComponent 中,例如:שלום、מה שלומך שמי הוא האקזיד',整个 JTextComponent 突然失去抗锯齿 - 永久。

奇怪的是,我什至没有扩展 AlloyTextPaneUI,而是扩展了 BasicTextPaneUI 来进行抗锯齿,所以我对 Alloy 出现在图片中的位置感到困惑(其他 Look and Feels 似乎工作得很好)。

我很难追踪这个错误...有人遇到过同样的问题吗?

这是一个演示问题的简短示例:

import com.incors.plaf.alloy.AlloyLookAndFeel;
import com.incors.plaf.alloy.themes.glass.GlassTheme;

import javax.swing.*;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicTextPaneUI;
import javax.swing.text.BadLocationException;
import javax.swing.text.StyledDocument;
import java.awt.*;

public class Scrap {

    static {
        // NOTE: You need a license code for Alloy!
        AlloyLookAndFeel.setProperty("alloy.licenseCode", "your license here");

        UIManager.put("TextPaneUI", MyTextPaneUI.class.getName());

        try {
            UIManager.setLookAndFeel(new AlloyLookAndFeel(new GlassTheme()));
        } catch (UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }

        // With system Look and Feel everything works just fine...
//      try {
//          UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
//      } catch (ClassNotFoundException e) {
//          e.printStackTrace();
//      } catch (InstantiationException e) {
//          e.printStackTrace();
//      } catch (IllegalAccessException e) {
//          e.printStackTrace();
//      } catch (UnsupportedLookAndFeelException e) {
//          e.printStackTrace();
//      }
    }

    public static void main(final String args[]) {
        JTextPane text = new JTextPane();

        text.setFont(new Font("Monospaced", Font.PLAIN, 14));

        StyledDocument doc = text.getStyledDocument();

        try {

            doc.insertString(doc.getLength(), "Here's some regular text. Nice and smooth with anti-aliasing.\n\n", null);

            doc.insertString(doc.getLength(), "Here's some more text Blaa Blaa Blaaa. Lorem ipsum... now try to uncomment the Hebrew text.\n\n", null);

            // Try to uncomment this line and the anti-aliasing breaks for the whole JTextPane
//          doc.insertString(doc.getLength(), "שלום, מה שלומך שמי הוא האקזידן\n\n", null);

            // Here's another strange glyph that breaks the anti-aliasing
//          doc.insertString(doc.getLength(), "ಠ", null);

        } catch (BadLocationException e) {
            e.printStackTrace();
        }

        JFrame frame = new JFrame();

        JScrollPane scroll = new JScrollPane();
        scroll.setViewportView(text);
        scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

        frame.add(scroll, BorderLayout.CENTER);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setSize(600, 300);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static class MyTextPaneUI extends BasicTextPaneUI {

        @Override
        protected void paintSafely(Graphics g) {
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(
                            RenderingHints.KEY_TEXT_ANTIALIASING,
                            RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
            super.paintSafely(g);
        }

        public static ComponentUI createUI(JComponent c) {
            return new MyTextPaneUI();
        }
    }
}

【问题讨论】:

  • 我不知道有什么问题,但是,张贴一些前后文本的屏幕截图,SSCCE 也不会受到伤害。只是为了获得更多信息,最好不要对某些文本进行抗锯齿处理……否则可能会发生模糊。阅读Displaying Antialiased Text by Using Rendering Hints
  • 好吧,我添加了一个简短的例子来演示这个问题,你可以自己看看抗锯齿是如何分解的。在这种情况下,使用非抗锯齿文本肯定是不可取的,它会使文本看起来非常糟糕(尤其是我在我的应用程序中使用的字体 - Consolas)。

标签: java swing look-and-feel jtextpane antialiasing


【解决方案1】:

经过一些非常令人沮丧的实验后,我修复了它。我仍然不确定究竟是什么原因造成的,但这是我修复它的方法。 Alloy 的 UIDefaults 中显然缺少/损坏了一个键(我不知道是哪一个)。因此,我将初始外观和感觉中的所有默认值添加到合金属性中。这是一种快速而肮脏的解决方案(我遇到的唯一问题是菜单变得不透明),但它足以满足我的需求。也许其他人也觉得它有帮助。

AlloyLookAndFeel laf = new AlloyLookAndFeel(theme) {
    @Override
    public UIDefaults getDefaults() {
        UIDefaults defs = new UIDefaults();

        defs.putAll(UIManager.getLookAndFeelDefaults());

        initClassDefaults(defs);
        initSystemColorDefaults(defs);
        initComponentDefaults(defs);

        defs.put("Menu.opaque", true);

        return defs;
    }
};

【讨论】:

    【解决方案2】:

    我有同样的问题很长时间了。将“Menu.opaque”属性设置为 true 的建议解决方案确实有助于使文本抗锯齿(奇怪),但它弄乱了我的菜单的外观,我不得不放弃它。

    这里真正的问题是,Alloy L&F 的支持很差,但根据我的经验,它看起来确实不错,并且性能非常好。在反编译混淆代码(Alloy Look&Feel v1.4.4)后,我将问题追溯到一种方法:

    public class AlloyLookAndFeel extends BasicLookAndFeel{
        ...
        private static boolean j = false;
        ...
        public static boolean isTextAntialiasingEnabled()  {
            return j;
        }
        ...
    }
    

    我找不到以编程方式更改值的方法,并且无法覆盖静态方法。所以我不得不求助于一些黑客行为:

    1. 使用 JD 反编译代码(参见http://jd.benow.ca/)。代码被混淆了,所以变量和方法名没有多大意义。
    2. 将 com.incors.plaf.alloy.AlloyLookAndFeel 的代码复制到依赖合金 LAF 的项目中(包名必须相同)
    3. 修正j的值

      private static boolean j = <strong>true</strong>;

    4. 有一个布尔 f.b 变量在反编译后无法访问的小问题,因此用 fbValue 替换所有出现的 f.b 并向类添加声明(调试器将帮助您找到当前值,在我的情况下它是 false)。

      private static boolean fbVariable = false;

    编译项目后,您应该有文本反锯齿。 这是一个 hack,但这是你必须做的,以保存一个好的,但受到严重支持的库。我希望有人有一个更简单的解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-18
      • 1970-01-01
      • 2013-04-11
      • 1970-01-01
      • 1970-01-01
      • 2016-06-28
      • 2011-07-05
      • 2014-03-19
      相关资源
      最近更新 更多