4

ここでAlloyLookand Feelを使用している人はいますか?アンチエイリアシングとJTextComponentsで奇妙なバグに直面しています。Alloyはデフォルトでアンチエイリアシングをまったく使用しないため、独自のUIクラスを作成して強制する必要があります。これはほとんどの場合正常に機能しますが、アンチエイリアシングに大混乱をもたらす特定の文字があります。

たとえば、Alloyがルックアンドフィールとして設定されていて、ヘブライ語のテキストをJTextComponentに挿入した場合、たとえば、שלום、מהשלומךשמיהואהאקזיד'の場合、JTextComponent全体が突然アンチエイリアスを失います。

奇妙なことに、AlloyTextPaneUIを拡張することすらしていませんが、アンチエイリアシングを行うためにBasicTextPaneUIを拡張しているため、Alloyが画像のどこに現れるのか戸惑っています(他のルックアンドフィールは問題なく機能しているようです)。

私はこのバグを追跡するのに非常に苦労しています...誰かが同じ問題に直面しましたか?

問題を示す短い例を次に示します。

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

2 に答える 2

3

いくつかの非常に苛立たしい実験の後、私はそれを修正しました..正確に何が原因であるかはまだわかりませんが、これが私がそれを修正した方法です。Alloyの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;
    }
};
于 2013-01-19T05:56:18.787 に答える
0

私は非常に長い間同じ問題を抱えていました。「Menu.opaque」プロパティをtrueに設定する提案された解決策は、テキストをアンチエイリアス(奇妙な)にするのに役立ちましたが、メニューの外観が混乱し、それを放棄する必要がありました。

ここでの本当の問題は、Alloy L&Fのサポートが不十分であるということですが、私の経験からすると、見た目は良く、パフォーマンスも非常に優れています。難読化されたコード(Alloy Look&Feel v1.4.4)を逆コンパイルした後、問題を1つの方法にたどりました。

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のコードをalloyLAFに依存するプロジェクトにコピーします(パッケージ名は同じである必要があります)
  3. jの値を修正する

    private static boolean j = true;

  4. 逆コンパイル後にブールfb変数にアクセスできないという小さな問題があったため、fbのすべての出現箇所をfbValueに置き換え、クラスに宣言を追加します(デバッガーは、現在の値を見つけるのに役立ちます。私の場合はfalseです)。

    private static boolean fbVariable = false;

プロジェクトをコンパイルした後、テキストのアンチエイリアスが必要になります。これはハックですが、これは、適切であるがサポートが不十分なライブラリを保存するために実行する必要があることです。誰かがもっと簡単な解決策を持っていることを願っています。

于 2014-10-02T13:42:36.353 に答える