* Copyright 2006-2020 The MZmine Development Team
 * This file is part of MZmine.
 * MZmine is free software; you can redistribute it and/or modify it under the terms of the GNU
 * General Public License as published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 * MZmine is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 * You should have received a copy of the GNU General Public License along with MZmine; if not,
 * write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 * USA

package io.github.mzmine.gui.framework;

import java.awt.Container;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.text.AbstractDocument;
import javax.swing.text.BoxView;
import javax.swing.text.ComponentView;
import javax.swing.text.Element;
import javax.swing.text.IconView;
import javax.swing.text.LabelView;
import javax.swing.text.ParagraphView;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledEditorKit;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;

public class CustomTextPane extends JTextPane {
  private boolean lineWrap;

  public CustomTextPane(final boolean lineWrap) {
    this.lineWrap = lineWrap;

    if (lineWrap)
      setEditorKit(new WrapEditorKit());

  public boolean getScrollableTracksViewportWidth() {
    if (lineWrap)
      return super.getScrollableTracksViewportWidth();
    else {
      Container parent = SwingUtilities.getUnwrappedParent(this);
      return parent == null || getUI().getPreferredSize(this).width <= parent.getSize().width;

  private class WrapEditorKit extends StyledEditorKit {
    private final ViewFactory defaultFactory = new WrapColumnFactory();

    public ViewFactory getViewFactory() {
      return defaultFactory;

  private class WrapColumnFactory implements ViewFactory {
    public View create(final Element element) {
      final String kind = element.getName();
      if (kind != null) {
        switch (kind) {
          case AbstractDocument.ContentElementName:
            return new WrapLabelView(element);
          case AbstractDocument.ParagraphElementName:
            return new ParagraphView(element);
          case AbstractDocument.SectionElementName:
            return new BoxView(element, View.Y_AXIS);
          case StyleConstants.ComponentElementName:
            return new ComponentView(element);
          case StyleConstants.IconElementName:
            return new IconView(element);

      // Default to text display.
      return new LabelView(element);

  private class WrapLabelView extends LabelView {
    public WrapLabelView(final Element element) {

    public float getMinimumSpan(final int axis) {
      switch (axis) {
        case View.X_AXIS:
          return 0;
        case View.Y_AXIS:
          return super.getMinimumSpan(axis);
          throw new IllegalArgumentException("Invalid axis: " + axis);