/* * Copyright 2014-2017 ieclipse.cn. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package cn.ieclipse.smartim.common; import javax.swing.*; import javax.swing.text.*; import javax.swing.text.html.HTML; import javax.swing.text.html.HTMLEditorKit; import javax.swing.text.html.InlineView; import javax.swing.text.html.ParagraphView; /** * 类/接口描述 * * @author Jamling * @date 2017年12月27日 */ public class WrapHTMLFactory extends HTMLEditorKit.HTMLFactory { public static final String SEPARATOR = System.getProperty("line.separator"); @Override public View create(Element elem) { View v = super.create(elem); if (v instanceof LabelView) { // the javax.swing.text.html.BRView (representing <br> tag) is a // LabelView but must not be handled // by a WrapLabelView. As BRView is private, check the html tag from // elem attribute Object o = elem.getAttributes().getAttribute(StyleConstants.NameAttribute); if ((o instanceof HTML.Tag) && o == HTML.Tag.BR) { return new BRView(elem); } } if (v instanceof InlineView) { return new WrapInlineView(elem); } else if (v instanceof ParagraphView) { return new WrapParagraphView(elem); } return v; } /** * Processes the <BR> tag. In other words, forces a line break. * * @author Sunita Mani */ class BRView extends InlineView { /** * Creates a new view that represents a <BR> element. * * @param elem the element to create a view for */ public BRView(Element elem) { super(elem); } /** * Forces a line break. * * @return View.ForcedBreakWeight */ public int getBreakWeight(int axis, float pos, float len) { if (axis == X_AXIS) { return ForcedBreakWeight; } else { return super.getBreakWeight(axis, pos, len); } } } class WrapInlineView extends InlineView { public WrapInlineView(Element elem) { super(elem); } @Override public int getBreakWeight(int axis, float pos, float len) { // return GoodBreakWeight; if (axis == View.X_AXIS) { checkPainter(); int p0 = getStartOffset(); int p1 = getGlyphPainter().getBoundedPosition(this, p0, pos, len); if (p1 == p0) { // can't even fit a single character return View.BadBreakWeight; } try { // if the view contains line break char return forced break String text = getDocument().getText(p0, p1 - p0); if (text.indexOf(WrapHTMLFactory.SEPARATOR) >= 0) { return View.ForcedBreakWeight; } } catch (BadLocationException ex) { // should never happen } } return super.getBreakWeight(axis, pos, len); } 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); try { // if the view contains line break char break the view int index = getDocument().getText(p0, p1 - p0).indexOf(WrapHTMLFactory.SEPARATOR); if (index >= 0) { GlyphView v = (GlyphView)createFragment(p0, p0 + index + 1); return v; } } catch (BadLocationException ex) { // should never happen } } return super.breakView(axis, p0, pos, len); } } class WrapParagraphView extends ParagraphView { public WrapParagraphView(Element elem) { super(elem); } @Override 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; } } ; }