Надлежащим образом создайте Class, JTree, DefaultTreeCellRenderer, используя JTextPane
У меня есть этот класс, чтобы показать несколько цветов в листе, используя JTree...
Класс TextPaneDefaultTreeCellRenderer
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;
}
}
Альтернативный класс TreeCellRendererTextPane
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;
}
}
Как видите, Root (не лист не отображается должным образом, папка опущена, в словах отображается только первая буква)
Мой другой класс DecoratedText
:
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;
}
}
Проблема с первым классом (TextPaneDefaultTreeCellRenderer) заключается в том, что это nullpointerexception использует nimbus LAF, но с другим LAF, aqua, metal, motif, gtk и windows проблема не представлена.
И пытаясь сделать "Разделяй и властвуй", этот вопрос не о том, что не получается? еще хорошо реализован мой класс?
1 ответ
Проблема с первым классом (TextPaneDefaultTreeCellRenderer) заключается в том, что это исключение nullpointerexception с использованием нимба LAF, ...
Даже при использовании NimbusLookAndFeel
в моем окружении (1.8.0_181, Windows 10) NullPointerException
не происходит для TextPaneDefaultTreeCellRenderer
...
папка опущена
Было бы хорошо работает для макета JTextPane
а также JLabel
для значка в JPanel
и использовать это как TreeCellRenderer
,
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.logging.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.tree.*;
public class TextPaneTreeCellRendererTest {
public Component makeUI() {
JTree tree0 = new JTree(makeModel());
// JTree tree1 = new JTree(makeModel());
// tree1.setCellRenderer(new TextPaneDefaultTreeCellRenderer());
// JTree tree2 = new JTree(makeModel());
// tree2.setCellRenderer(new TextPaneTreeCellRenderer());
// JTree tree3 = new JTree(makeModel());
// tree3.setCellRenderer(new TreeCellRendererTextPane());
JTree tree = new JTree(makeModel());
tree.setRowHeight(24);
tree.setCellRenderer(new CustomTreeCellRenderer());
JTabbedPane tabs = new JTabbedPane();
tabs.add("DefaultTreeCellRenderer", new JScrollPane(tree0));
// tabs.add("TextPaneDefaultTreeCellRenderer", new JScrollPane(tree1));
// tabs.add("TextPaneTreeCellRenderer", new JScrollPane(tree2));
// tabs.add("TreeCellRendererTextPane", new JScrollPane(tree3));
tabs.add("CustomTreeCellRenderer", new JScrollPane(tree));
return tabs;
}
private static TreeModel makeModel() {
DefaultMutableTreeNode root = new DefaultMutableTreeNode("/Users/");
DefaultMutableTreeNode parent;
parent = new DefaultMutableTreeNode("<html>/Users/...<span style='color:red'>colors: <span style='color:blue'>blue");
root.add(parent);
String txt = "<html><span style='color:red'>Line 6</span> : <span style='color:blue'>!!!!!!!! on <span style='Color:green'>CentOS</span> 7</span>";
parent.add(new DefaultMutableTreeNode(txt));
parent.add(new DefaultMutableTreeNode(new DecoratedText("blue", Color.BLUE)));
parent.add(new DefaultMutableTreeNode(new DecoratedText("pink", Color.PINK)));
parent.add(new DefaultMutableTreeNode(new DecoratedText("red", Color.RED)));
return new DefaultTreeModel(root);
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
try {
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Exception e) {
e.printStackTrace();
}
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new TextPaneTreeCellRendererTest().makeUI());
f.setSize(640, 480);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
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;
}
}
class CustomTreeCellRenderer extends JPanel implements TreeCellRenderer {
private DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
private final JLabel icon = new JLabel();
private final JTextPane textPane = new JTextPane();
protected CustomTreeCellRenderer() {
super(new BorderLayout());
textPane.setContentType("text/html");
textPane.setEditable(false);
textPane.setOpaque(false);
icon.setOpaque(false);
setOpaque(false);
add(icon, BorderLayout.WEST);
add(textPane);
}
@Override public Component getTreeCellRendererComponent(
JTree tree, Object value, boolean selected, boolean expanded,
boolean leaf, int row, boolean hasFocus) {
JLabel l = (JLabel) renderer.getTreeCellRendererComponent(
tree, value, selected, expanded, leaf, row, hasFocus);
Color bgColor;
Color fgColor;
if (selected) {
bgColor = renderer.getBackgroundSelectionColor();
fgColor = renderer.getTextSelectionColor();
} else {
bgColor = Optional.ofNullable(renderer.getBackgroundNonSelectionColor())
.orElse(renderer.getBackground());
fgColor = Optional.ofNullable(renderer.getTextNonSelectionColor())
.orElse(renderer.getForeground());
}
UIDefaults defaults = new UIDefaults();
defaults.put("TextPane[Enabled].backgroundPainter", bgColor);
textPane.putClientProperty("Nimbus.Overrides", defaults);
textPane.putClientProperty("Nimbus.Overrides.InheritDefaults", true);
textPane.setBackground(bgColor);
textPane.setForeground(fgColor);
DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
Object object = node.getUserObject();
textPane.setText("");
Document doc = textPane.getStyledDocument();
if (object instanceof DecoratedText) {
DecoratedText decText = (DecoratedText) object;
try {
doc.insertString(doc.getLength(), decText.getText(), decText.getAttributeSet(textPane));
} catch (BadLocationException ex) {
ex.printStackTrace();
}
} else if (object instanceof DecoratedText[]) {
DecoratedText[] arrayDecText = (DecoratedText[]) object;
for (DecoratedText decText : arrayDecText) {
try {
doc.insertString(doc.getLength(), decText.getText(), decText.getAttributeSet(textPane));
} catch (BadLocationException ex) {
ex.printStackTrace();
}
}
} else {
textPane.setText(Objects.toString(value));
}
icon.setIcon(l.getIcon());
icon.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, l.getIconTextGap()));
return this;
}
@Override public void updateUI() {
super.updateUI();
renderer = new DefaultTreeCellRenderer();
}
}