3

JTextPane とぶら下げインデントで厄介な小さなバグに直面しています。

簡単な例を次に示します。

public class Scrap {

public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(200, 200);
    frame.setLayout(new BorderLayout());

    JTextPane textPane = new JTextPane();

    JScrollPane scroll = new JScrollPane(textPane);

    frame.add(scroll);

    StyledDocument doc = (StyledDocument) textPane.getDocument();

    try {

        String str = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum ";

        doc.insertString(doc.getLength(), str, null);

        // Hanging indent
        MutableAttributeSet mas = new SimpleAttributeSet();
        StyleConstants.setLeftIndent(mas, 20);
        StyleConstants.setFirstLineIndent(mas, -20);
        doc.setParagraphAttributes(0, str.length(), mas, false);

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

    frame.setVisible(true);
    frame.setLocationRelativeTo(null);
}
}

私のコンピューターでは、Java 7 を使用しており、何らかの理由で最初の行が他の行よりも太字になっています...これを修正する方法を知っている人はいますか?

4

3 に答える 3

1

私はこれに戻り、それを修正しました!少なくとも私のニーズには十分です。問題は、私が推測したように、JTextPaneが最初の行を2回描画したことでした。

Oracleは私のバグレポートを都合よく無視しました。彼らはもうSwingを気にしないと思います。

修正は次のとおりです(どこかで見つけたJava 7のロングワードラップ修正を含む):

import javax.swing.*;
import javax.swing.text.Element;
import javax.swing.text.ParagraphView;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.InlineView;
import java.awt.*;

/**
 * A fixed HTML Editor Kit, which fixes two things:
 * - Word wrapping of long words (bugged in Java 7)
 * - A hanging indent bug
 */
public class FixedHtmlEditorKit extends HTMLEditorKit {

@Override
public ViewFactory getViewFactory() {
    return new HTMLEditorKit.HTMLFactory() {
        public View create(Element e) {
            View v = super.create(e);

            if (v instanceof InlineView) {
                return new InlineView(e) {
                    public int getBreakWeight(int axis, float pos, float len) {
                        return GoodBreakWeight;
                    }

                    public View breakView(int axis, int p0, float pos, float len) {
                        if (axis == View.X_AXIS) {
                            checkPainter();
                            int p1 = getGlyphPainter().getBoundedPosition(this, p0, pos, len);
                            if (p0 == getStartOffset() && p1 == getEndOffset()) {
                                return this;
                            }
                            return createFragment(p0, p1);
                        }
                        return this;
                    }
                };
            }
            else if (v instanceof ParagraphView) {
                return new ParagraphView(e) {
                    protected SizeRequirements calculateMinorAxisRequirements(int axis, SizeRequirements r) {
                        if (r == null) {
                            r = new SizeRequirements();
                        }
                        float pref = layoutPool.getPreferredSpan(axis);
                        float min = layoutPool.getMinimumSpan(axis);
                        // Don't include insets, Box.getXXXSpan will include them.
                        r.minimum = (int) min;
                        r.preferred = Math.max(r.minimum, (int) pref);
                        r.maximum = Integer.MAX_VALUE;
                        r.alignment = 0.5f;
                        return r;
                    }

                    private boolean allowedToPaintFirstView = true;

                    private float tabBase;

                    /*
                     * We need to override this since tabBase is private in ParagraphView.
                     */
                    @Override
                    protected float getTabBase() {
                        return tabBase;
                    }

                    @Override
                    protected void paintChild(Graphics g, Rectangle alloc, int index) {
                        // Don't paint the first index twice!
                        if (index == 0 && !allowedToPaintFirstView) {
                            return;
                        }
                        super.paintChild(g, alloc, index);
                    }


                    public void paint(Graphics g, Shape a) {
                        Rectangle alloc = (a instanceof Rectangle) ? (Rectangle)a : a.getBounds();

                        tabBase = alloc.x + getLeftInset();

                        // line with the negative firstLineIndent value needs
                        // special handling
                        if (firstLineIndent < 0) {
                            Shape sh = getChildAllocation(0, a);
                            if ((sh != null) &&  sh.intersects(alloc)) {
                                int x = alloc.x + getLeftInset() + firstLineIndent;
                                int y = alloc.y + getTopInset();

                                Rectangle clip = g.getClipBounds();
                                Rectangle tempRect = new Rectangle();
                                tempRect.x = x + getOffset(X_AXIS, 0);
                                tempRect.y = y + getOffset(Y_AXIS, 0);
                                tempRect.width = getSpan(X_AXIS, 0) - firstLineIndent;
                                tempRect.height = getSpan(Y_AXIS, 0);
                                if (tempRect.intersects(clip)) {
                                    tempRect.x = tempRect.x - firstLineIndent;
                                    allowedToPaintFirstView = true;
                                    paintChild(g, tempRect, 0);
                                    allowedToPaintFirstView = false;
                                }
                            }
                        }

                        super.paint(g, a);
                    }
                };
            }
            return v;
        }
    };
}

}

于 2013-01-07T12:54:12.637 に答える
0

私が間違っていなければ、デフォルトで多くのコントロールに太字のフォントを使用する MetalLookAndFeel を使用している可能性があります。

これを試して、主な方法で金属の太字フォントの使用をオフにします。

    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            //Turn off metal's use of bold fonts
        UIManager.put("swing.boldMetal", Boolean.FALSE);
            createAndShowGUI();
        }
    });
于 2012-10-10T11:23:33.367 に答える