/* * Jitsi, the OpenSource Java VoIP and Instant Messaging client. * * Copyright @ 2015 Atlassian Pty Ltd * * 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 net.java.sip.communicator.plugin.desktoputil; import java.awt.*; import javax.swing.*; import javax.swing.text.*; import javax.swing.text.html.*; import javax.swing.text.html.ParagraphView; /** * The <tt>SIPCommHTMLEditorKit</tt> is an <tt>HTMLEditorKit</tt> which uses * an extended <tt>ParagraphView</tt>. * * @author Yana Stamcheva */ public class SIPCommHTMLEditorKit extends HTMLEditorKit { /** * Serial version UID. */ private static final long serialVersionUID = 0L; private final JComponent container; /** * Creates an instance of <tt>SIPCommHTMLEditorKit</tt> by specifying the * container, where the editor kit would be used. * * @param container */ public SIPCommHTMLEditorKit(JComponent container) { this.container = container; } /** * Returns the extended <tt>HTMLFactory</tt> defined here. * * @return the extended view factory */ @Override public ViewFactory getViewFactory() { return new HTMLFactoryX(); } /** * An extended <tt>HTMLFactory</tt> that uses the <tt>SIPCommImageView</tt> * to represent images and the <tt>ParagraphViewX</tt> to represent * paragraphs. */ private class HTMLFactoryX extends HTMLFactory implements ViewFactory { @Override public View create(Element elem) { View view = super.create(elem); viewCreated(this, view); if (view instanceof ParagraphView) { return new ParagraphViewX(elem); } else if (view instanceof ComponentView) { return new MyComponentView(elem); } return view; } } /** * Inform extenders for the view creation. * @param view the newly created view. */ protected void viewCreated(ViewFactory factory, View view){} /** * An extended component view, which provides horizontal and vertical * filling. */ private class MyComponentView extends ComponentView { /** * Creates a new ComponentView object. * * @param elem the element to decorate */ public MyComponentView(Element elem) { super(elem); } /** * Determines the preferred span for this view along an * axis. This is implemented to return the value * returned by Component.getPreferredSize along the * axis of interest. * * @param axis may be either View.X_AXIS or View.Y_AXIS * @return the span the view would like to be rendered into >= 0. * Typically the view is told to render into the span * that is returned, although there is no guarantee. * The parent may choose to resize or break the view. * @exception IllegalArgumentException for an invalid axis */ @Override public float getPreferredSpan(int axis) { if ((axis != X_AXIS) && (axis != Y_AXIS)) { throw new IllegalArgumentException("Invalid axis: " + axis); } if (getComponent() != null) { Dimension size = getComponent().getPreferredSize(); if (axis == View.X_AXIS) { return container.getWidth(); } else { return size.height; } } return 0; } /** * Determines the maximum span for this view along an * axis. This is implemented to return the value * returned by Component.getMaximumSize along the * axis of interest. * * @param axis may be either View.X_AXIS or View.Y_AXIS * @return the span the view would like to be rendered into >= 0. * Typically the view is told to render into the span * that is returned, although there is no guarantee. * The parent may choose to resize or break the view. * @exception IllegalArgumentException for an invalid axis */ @Override public float getMaximumSpan(int axis) { if ((axis != X_AXIS) && (axis != Y_AXIS)) { throw new IllegalArgumentException("Invalid axis: " + axis); } if (getComponent() != null) { Dimension size = getComponent().getMaximumSize(); if (axis == View.X_AXIS) { return container.getWidth(); } else { return size.height; } } return 0; } } /** * The <tt>ParagraphViewX</tt> is created in order to solve the following * problem (Bug ID: 4855207): * <p> * When a paragraph in a JTextPane has a large amount of text the * processing needed to layout the entire paragraph increases as the * paragraph grows. */ static class ParagraphViewX extends ParagraphView { /** * Creates an instance of <tt>ParagraphViewX</tt>. * * @param elem the element that this view is responsible for */ public ParagraphViewX(Element elem) { super(elem); } /** * Calculate requirements along the minor axis. This * is implemented to forward the request to the logical * view by calling getMinimumSpan, getPreferredSpan, and * getMaximumSpan on it. * * @param axis the axis, for which we calculate size requirements * @param sizeRequirements the initial size requirements * @return the recalculated size requirements for the given axis */ @Override protected SizeRequirements calculateMinorAxisRequirements ( int axis, SizeRequirements sizeRequirements) { if (sizeRequirements == null) { sizeRequirements = new SizeRequirements(); } float pref = layoutPool.getPreferredSpan(axis); float min = layoutPool.getMinimumSpan(axis); // Don't include insets, Box.getXXXSpan will include them. sizeRequirements.minimum = (int)min; sizeRequirements.preferred = Math.max(sizeRequirements.minimum, (int) pref); sizeRequirements.maximum = Short.MAX_VALUE; sizeRequirements.alignment = 0.5f; return sizeRequirements; } } }