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