Manera adecuada crear Class, JTree, DefaultTreeCellRenderer usando JTextPane

Tengo esta clase para mostrar múltiples colores en una hoja usando JTree ...

La clase esTextPaneDefaultTreeCellRenderer

import java.awt.*;
import java.util.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.tree.*;

public class TextPaneDefaultTreeCellRenderer extends DefaultTreeCellRenderer {

  TextPaneTreeCellRenderer textPaneScrollPane = new TextPaneTreeCellRenderer();

  public TextPaneDefaultTreeCellRenderer() {
    initialize();
  }

  private void initialize() {
    textPaneScrollPane.setBackgroundNonSelectionColor(getBackgroundNonSelectionColor());
    textPaneScrollPane.setBackgroundSelectionColor(getBackgroundSelectionColor());
    textPaneScrollPane.setTextNonSelectionColor(getTextNonSelectionColor());
    textPaneScrollPane.setTextSelectionColor(getTextSelectionColor());
  }

  @Override
  public Component getTreeCellRendererComponent(JTree tree,
      Object value, boolean selected, boolean expanded, boolean leaf,
      int row, boolean hasFocus) {
    if (leaf) {
      DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
      Object obj = node.getUserObject();
      if (obj != null) {
        if (obj instanceof DecoratedText || obj instanceof DecoratedText[]) {
          if (textPaneScrollPane == null) {
            System.out.println("textPaneScrollPane:" + textPaneScrollPane);
          }
          return textPaneScrollPane.getTreeCellRendererComponent(tree, value,
              selected, expanded, leaf, row, hasFocus);
        }
      }
    }
    return super.getTreeCellRendererComponent(tree, value, selected,
        expanded, leaf, row, hasFocus);
  }
}

class TextPaneTreeCellRenderer extends DefaultTreeCellRenderer {

  JTextPane textPane;

  public TextPaneTreeCellRenderer() {
    textPane = new JTextPane();
    add(textPane);
  }

  @Override
  public void setBackgroundNonSelectionColor(Color color) {
    this.backgroundNonSelectionColor = color;
  }

  @Override
  public void setBackgroundSelectionColor(Color color) {
    this.backgroundSelectionColor = color;
  }

  @Override
  public void setTextNonSelectionColor(Color color) {
    this.textNonSelectionColor = color;
  }

  @Override
  public void setTextSelectionColor(Color color) {
    this.textSelectionColor = color;
  }

  @Override
  public Component getTreeCellRendererComponent(JTree tree,
      Object value, boolean selected, boolean expanded, boolean leaf,
      int row, boolean hasFocus) {

    DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
    Object object = node.getUserObject();

    if (selected) {
      setForeground(textSelectionColor);
      setBackground(backgroundSelectionColor);
      textPane.setForeground(textSelectionColor);
      textPane.setBackground(backgroundSelectionColor);
    } else {
      setForeground(textNonSelectionColor);
      setBackground(backgroundNonSelectionColor);
      textPane.setForeground(textNonSelectionColor);
      textPane.setBackground(backgroundNonSelectionColor);
    }

    textPane.setText("");
    Document doc = textPane.getStyledDocument();
    if (object != null && object instanceof DecoratedText) {
      DecoratedText decText = (DecoratedText) object;
      try {
        doc.insertString(doc.getLength(), decText.getText(), getAttributeSet(decText));
      } catch (BadLocationException ex) {
        Logger.getLogger(TextPaneTreeCellRenderer.class.getName()).log(Level.SEVERE, null, ex);
      }
    } else if (object != null && object instanceof DecoratedText[]) {
      DecoratedText[] arrayDecText = (DecoratedText[]) object;
      for (DecoratedText decText : arrayDecText) {
        try {
          //doc.insertString(doc.getLength(), decText.getText(), getAttributeSet(decText));
          doc.insertString(doc.getLength(), decText.getText(), decText.getAttributeSet(textPane));
        } catch (BadLocationException ex) {
          System.out.println("decText:" + decText);
          System.out.println("arrayDecText:" + arrayDecText);
          System.out.println("doc:" + doc.getLength());
          Logger.getLogger(TextPaneTreeCellRenderer.class.getName()).log(Level.SEVERE, null, ex);
        }
      }
    } else {
      return new DefaultTreeCellRenderer().getTreeCellRendererComponent(tree,
          value, leaf, expanded, leaf, row, hasFocus);
    }
    return textPane;
  }

  private SimpleAttributeSet getAttributeSet(DecoratedText decoratedText) {
    SimpleAttributeSet attrSet = new SimpleAttributeSet();
    if (decoratedText != null) {
      if (decoratedText.getBackground() != null) {
        StyleConstants.setBackground(attrSet, decoratedText.getBackground());
      } else {
        StyleConstants.setBackground(attrSet, textPane.getBackground());
      }
      if (decoratedText.getForeground() != null) {
        StyleConstants.setForeground(attrSet, decoratedText.getForeground());
      } else {
        StyleConstants.setForeground(attrSet, textPane.getForeground());
      }
      Font font;
      if (decoratedText.getFont() != null) {
        font = decoratedText.getFont();
      } else {
        font = textPane.getFont();
      }
      StyleConstants.setFontFamily(attrSet, font.getFamily());
      StyleConstants.setItalic(attrSet, font.isItalic());
      StyleConstants.setBold(attrSet, font.isBold());
      StyleConstants.setFontSize(attrSet, font.getSize());
    }
    return attrSet;
  }

}

a clase @Alternative esTreeCellRendererTextPane

import java.awt.Component;
import java.util.logging.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.tree.*;

public class TreeCellRendererTextPane extends JTextPane implements TreeCellRenderer {

  @Override
  public Component getTreeCellRendererComponent(JTree tree,
      Object value, boolean selected, boolean expanded, boolean leaf,
      int row, boolean hasFocus) {
    if (leaf) {
      DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
      Object obj = node.getUserObject();
      if (obj != null) {
        if (obj instanceof DecoratedText || obj instanceof DecoratedText[]) {
          this.setText("");
          Document doc = this.getStyledDocument();
          if (obj instanceof DecoratedText) {
            DecoratedText decText = (DecoratedText) obj;
            try {
              doc.insertString(doc.getLength(), decText.getText(), decText.getAttributeSet(this));
            } catch (BadLocationException ex) {
              Logger.getLogger(TextPaneTreeCellRenderer.class.getName()).log(Level.SEVERE, null, ex);
            }
          }
          if (obj instanceof DecoratedText[]) {
            DecoratedText[] arrayDecText = (DecoratedText[]) obj;
            for (DecoratedText decText : arrayDecText) {
              try {
                doc.insertString(doc.getLength(), decText.getText(), decText.getAttributeSet(this));
              } catch (BadLocationException ex) {
                System.out.println("decText:" + decText);
                System.out.println("arrayDecText:" + arrayDecText);
                System.out.println("doc:" + doc.getLength());
                Logger.getLogger(TextPaneTreeCellRenderer.class.getName()).log(Level.SEVERE, null, ex);
              }
            }
          }
        } else {
          return new DefaultTreeCellRenderer().getTreeCellRendererComponent(tree,
              value, leaf, expanded, leaf, row, hasFocus);
        }
      }
    }
    return this;
  }
}

Como puede ver la raíz (no se muestra la hoja correctamente, se omite la carpeta, las palabras solo muestran la primera letra)

Mi otra clase esDecoratedText:

import java.awt.*;
import javax.swing.JTextPane;
import javax.swing.text.*;

public class DecoratedText {

  private String text;
  private Color background;// = new JLabel().getBackground();
  private Color foreground;// = new JLabel().getForeground();
  private Font font;// = new JLabel().getFont();

  public DecoratedText(String text) {
    this.text = text;
  }

  public DecoratedText(String text, Font font) {
    this.text = text;
    this.font = font;
  }

  public DecoratedText(String text, Color foreground) {
    this.text = text;
    this.foreground = foreground;
  }

  public DecoratedText(String text, Color foreground, Font font) {
    this.text = text;
    this.foreground = foreground;
    this.font = font;
  }

  public DecoratedText(Color background, String text) {
    this.background = background;
    this.text = text;
  }

  public DecoratedText(Color background, String text, Font font) {
    this.background = background;
    this.text = text;
    this.font = font;
  }

  public DecoratedText(Color background, String text, Color foreground) {
    this.background =, background;
    this.text = text;
    this.foreground = foreground;
  }

  public DecoratedText(Color background, String text, Color foreground, Font font) {
    this.background = background;
    this.text = text;
    this.foreground = foreground;
    this.font = font;
  }

  public String getText() {
    return text;
  }

  public void setText(String text) {
    this.text = text;
  }

  public Color getBackground() {
    return background;
  }

  public void setBackground(Color background) {
    this.background = background;
  }

  public Color getForeground() {
    return foreground;
  }

  public void setForeground(Color foreground) {
    this.foreground = foreground;
  }

  public Font getFont() {
    return font;
  }

  public void setFont(Font font) {
    this.font = font;
  }

  @Override
  public String toString() {
    return "DecoratedText{" + "text=" + text + ", background=" + background
        + ", foreground=" + foreground + ", font=" + font + "}";
  }

  public SimpleAttributeSet getAttributeSet(JTextPane textPane) {
    SimpleAttributeSet attrSet = new SimpleAttributeSet();
    if (getBackground() != null) {
      StyleConstants.setBackground(attrSet, getBackground());
    } else {
      StyleConstants.setBackground(attrSet, textPane.getBackground());
    }
    if (getForeground() != null) {
      StyleConstants.setForeground(attrSet, getForeground());
    } else {
      StyleConstants.setForeground(attrSet, textPane.getForeground());
    }
    Font font;
    if (getFont() != null) {
      font = getFont();
    } else {
      font = textPane.getFont();
    }
    StyleConstants.setFontFamily(attrSet, font.getFamily());
    StyleConstants.setItalic(attrSet, font.isItalic());
    StyleConstants.setBold(attrSet, font.isBold());
    StyleConstants.setFontSize(attrSet, font.getSize());
    return attrSet;
  }

}

El problema con la primera clase TextPaneDefaultTreeCellRenderer) Es estonullpointerexception usandonimb LAF, pero con otro LAF,agu, meta, motiv, gtk y windows el problema no se presenta.

Y tratando de dividir y conquistar, esta pregunta no se trata de ¿Qué falla? else ¿Está bien implementado mi clase?

Descubre la razón de NullPointerException en clases nativas de Java, SynthTreeUI usando LAF Nimbus

Respuestas a la pregunta(1)

Su respuesta a la pregunta