JTextPane和悬挂缩进故障

JTextPane和悬挂缩进故障

本文介绍了JTextPane和悬挂缩进故障的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正用JTextPane面对一个烦人的小错误,并悬挂了缩进.

I'm facing an annoying little bug with JTextPane and hanging indent.

这是一个简单的例子:

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的计算机上,由于某些原因,第一行比其他行大胆……任何人都知道如何解决此问题?

On my computer, with Java 7, the first row is bolder than the other rows for some reason... Anyone have ideas how to fix this?

推荐答案

我回到了这一点,并且已经解决了!至少足以满足我的需求.正如我所怀疑的那样,问题是JTextPane绘制了第一行两次.

I got back to this, and I got it fixed! At least well enough for my needs. The problem was, as I suspected, that JTextPane drew the first line twice.

Oracle方便地忽略了我的错误报告,我想他们只是不再关心Swing.

Oracle conveniently ignored my bug report, I guess they just don't care about Swing anymore.

这里是修复程序(包括我从某处找到的Java 7的长条自动换行修复程序):

Here's the fix (including the long word wrap fix for Java 7, which I found from somewhere):

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

}

这篇关于JTextPane和悬挂缩进故障的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 01:08