正确的方式使用JTextPane创建Class,JTree,DefaultTreeCellRenderer

我有这个类,以便使用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 )的问题是这个使用nimbus LAF的nullpointerexception ,但是对于另一个LAF, aquametalmotifgtkwindows ,问题没有呈现。

并试图做分而治之,这个问题不是关于什么失败了? 否则我的class级很好实施?

使用LAF Nimbus在Java Native Classes,SynthTreeUI中发现NullPointerException的原因

第一个类(TextPaneDefaultTreeCellRenderer)的问题是这个使用nimbus LAF的nullpointerexception,…

即使在我的环境中使用NimbusLookAndFeel (1.8.0_181,Windows 10), TextPaneDefaultTreeCellRenderer也不会发生NullPointerException

文件夹被省略

JPanel中将JTextPaneJLabel布局为图标并将其用作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("/Users/...colors: blue"); root.add(parent); String txt = "Line 6 : !!!!!!!! on CentOS 7"; 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(); } }