合金外观和抗锯齿

时间:2013-01-17 16:55:52

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

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

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

奇怪的是我甚至没有扩展AlloyTextPaneUI,而是使用BasicTextPaneUI进行消除锯齿,所以我很困惑合金进入图片的位置(其他外观看起来效果很好)。

我很难追查这个错误......任何人都面临同样的问题?

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

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();
        }
    }
}

2 个答案:

答案 0 :(得分:3)

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

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;
    }
};

答案 1 :(得分:0)

我在很长一段时间内遇到过同样的问题。设置" Menu.opaque"的建议解决方案属性为true确实有助于使文本反锯齿(奇怪),但它与我的菜单看起来的方式混乱,我不得不放弃它。

这里真正的问题是合金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 = true;

  4. 在反编译后出现了一个布尔fb变量无法访问的小问题,所以用fbValue替换所有出现的fb并向类中添加一个声明(调试器将帮助你找到当前值,在我的例子中它是假的)。

    private static boolean fbVariable = false;

  5. 编译项目后,您应该使用文本反锯齿。 这是一个黑客,但这是你必须做的,以保存一个好的,但支持不当的库。我希望有人能有一个更容易的解决方案。