Java/Swing JFC/Tree Renderer Editor
Версия от 18:01, 31 мая 2010; (обсуждение)
Содержание
Build a tree and populate it with custom renderers and editors
/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O"Reilly
*/
// EmailTree.java
//A Simple test to see how we can build a tree and populate it. This
//application also uses custom renderers and editors.
//
import java.awt.BorderLayout;
import java.awt.ruponent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.EventObject;
import java.util.Hashtable;
import java.util.Vector;
import javax.swing.CellEditor;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellEditor;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellEditor;
public class EmailTree extends JFrame {
JTree tree;
String[][] addresses = {
{ "paul@work.domain", "ptw@work.domain", "other@volunteer.domain" },
{ "paul@home.domain" },
{ "damian@work.domain", "damian@bigisp.domain" },
{ "paged@pager.domain" },
{ "damian@home.domain", "mosh@home.domain" }, { "angela@home.ru" } };
public EmailTree() {
super("Hashtable Test");
setSize(400, 300);
setDefaultCloseOperation(EXIT_ON_CLOSE); // 1.3 & higher
// addWindowListener(new BasicWindowMonitor()); // 1.1 & 1.2
}
public void init() {
Hashtable h = new Hashtable();
Hashtable paul = new Hashtable();
paul.put("Work", addresses[0]);
paul.put("Home", addresses[1]);
Hashtable damian = new Hashtable();
damian.put("Work", addresses[2]);
damian.put("Pager", addresses[3]);
damian.put("Home", addresses[4]);
Hashtable angela = new Hashtable();
angela.put("Home", addresses[5]);
h.put("Paul", paul);
h.put("Damian", damian);
h.put("Angela", angela);
tree = new JTree(h);
DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) tree
.getCellRenderer();
renderer.setOpenIcon(new ImageIcon("mailboxdown.gif"));
renderer.setClosedIcon(new ImageIcon("mailboxup.gif"));
renderer.setLeafIcon(new ImageIcon("letter.gif"));
EmailTreeCellEditor emailEditor = new EmailTreeCellEditor();
DefaultTreeCellEditor editor = new DefaultTreeCellEditor(tree,
renderer, emailEditor);
tree.setCellEditor(editor);
tree.setEditable(true);
getContentPane().add(tree, BorderLayout.CENTER);
}
public static void main(String args[]) {
EmailTree tt = new EmailTree();
tt.init();
tt.setVisible(true);
}
}
//EmailTreeCellEditor.java
//An editor that actually manages two separate editors: one for folders
//(nodes) that uses a combobox; and one for files (leaves) that uses a
//textfield.
//
class EmailTreeCellEditor implements TreeCellEditor {
EditorComboBox nodeEditor;
EmailEditor leafEditor;
CellEditor currentEditor;
static String[] emailTypes = { "Home", "Work", "Pager", "Spam" };
public EmailTreeCellEditor() {
EmailEditor tf = new EmailEditor();
EditorComboBox cb = new EditorComboBox(emailTypes);
nodeEditor = cb;
leafEditor = tf;
}
public Component getTreeCellEditorComponent(JTree tree, Object value,
boolean isSelected, boolean expanded, boolean leaf, int row) {
if (leaf) {
currentEditor = leafEditor;
leafEditor.setText(value.toString());
} else {
currentEditor = nodeEditor;
nodeEditor.setSelectedItem(((DefaultMutableTreeNode) value)
.getUserObject());
}
return (Component) currentEditor;
}
public Object getCellEditorValue() {
return currentEditor.getCellEditorValue();
}
// All cells are editable in this example...
public boolean isCellEditable(EventObject event) {
return true;
}
public boolean shouldSelectCell(EventObject event) {
return currentEditor.shouldSelectCell(event);
}
public boolean stopCellEditing() {
return currentEditor.stopCellEditing();
}
public void cancelCellEditing() {
currentEditor.cancelCellEditing();
}
public void addCellEditorListener(CellEditorListener l) {
nodeEditor.addCellEditorListener(l);
leafEditor.addCellEditorListener(l);
}
public void removeCellEditorListener(CellEditorListener l) {
nodeEditor.removeCellEditorListener(l);
leafEditor.removeCellEditorListener(l);
}
}
//EditorComboBox.java
//A CellEditor JComboBox subclass for use with Trees (and possibly tables).
//This version will work with any list of values passed as an Object[].
//
class EditorComboBox extends JComboBox implements CellEditor {
String value;
Vector listeners = new Vector();
// Mimic all the constructors people expect with ComboBoxes.
public EditorComboBox(Object[] list) {
super(list);
setEditable(false);
value = list[0].toString();
// Listen to our own action events so that we know when to stop editing.
addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if (stopCellEditing()) {
fireEditingStopped();
}
}
});
}
// Implement the CellEditor methods.
public void cancelCellEditing() {
}
// Stop editing only if the user entered a valid value.
public boolean stopCellEditing() {
try {
value = (String) getSelectedItem();
if (value == null) {
value = (String) getItemAt(0);
}
return true;
} catch (Exception e) {
// Something went wrong.
return false;
}
}
public Object getCellEditorValue() {
return value;
}
// Start editing when the right mouse button is clicked.
public boolean isCellEditable(EventObject eo) {
if ((eo == null)
|| ((eo instanceof MouseEvent) && (((MouseEvent) eo)
.isMetaDown()))) {
return true;
}
return false;
}
public boolean shouldSelectCell(EventObject eo) {
return true;
}
// Add support for listeners.
public void addCellEditorListener(CellEditorListener cel) {
listeners.addElement(cel);
}
public void removeCellEditorListener(CellEditorListener cel) {
listeners.removeElement(cel);
}
protected void fireEditingStopped() {
if (listeners.size() > 0) {
ChangeEvent ce = new ChangeEvent(this);
for (int i = listeners.size() - 1; i >= 0; i--) {
((CellEditorListener) listeners.elementAt(i))
.editingStopped(ce);
}
}
}
}
//EmailEditor.java
//An extension of JTextField that requires an "@" somewhere in the field.
//Meant to be used as a cell editor within a JTable or JTree.
//
class EmailEditor extends JTextField implements CellEditor {
String value = "";
Vector listeners = new Vector();
// Mimic all the constructors people expect with text fields.
public EmailEditor() {
this("", 5);
}
public EmailEditor(String s) {
this(s, 5);
}
public EmailEditor(int w) {
this("", w);
}
public EmailEditor(String s, int w) {
super(s, w);
// Listen to our own action events so that we know when to stop editing.
addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if (stopCellEditing()) {
fireEditingStopped();
}
}
});
}
// Implement the CellEditor methods.
public void cancelCellEditing() {
setText("");
}
// Stop editing only if the user entered a valid value.
public boolean stopCellEditing() {
try {
String tmp = getText();
int at = tmp.indexOf("@");
if (at != -1) {
value = tmp;
return true;
}
return false;
} catch (Exception e) {
// Something went wrong (most likely we don"t have a valid integer).
return false;
}
}
public Object getCellEditorValue() {
return value;
}
// Start editing when the right mouse button is clicked.
public boolean isCellEditable(EventObject eo) {
if ((eo == null)
|| ((eo instanceof MouseEvent) && (((MouseEvent) eo)
.isMetaDown()))) {
return true;
}
return false;
}
public boolean shouldSelectCell(EventObject eo) {
return true;
}
// Add support for listeners.
public void addCellEditorListener(CellEditorListener cel) {
listeners.addElement(cel);
}
public void removeCellEditorListener(CellEditorListener cel) {
listeners.removeElement(cel);
}
protected void fireEditingStopped() {
if (listeners.size() > 0) {
ChangeEvent ce = new ChangeEvent(this);
for (int i = listeners.size() - 1; i >= 0; i--) {
((CellEditorListener) listeners.elementAt(i))
.editingStopped(ce);
}
}
}
}
CheckBox Node Tree Sample
/*
Definitive Guide to Swing for Java 2, Second Edition
By John Zukowski
ISBN: 1-893115-78-X
Publisher: APress
*/
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ruponent;
import java.awt.Font;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.util.EventObject;
import java.util.Vector;
import javax.swing.AbstractCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;
public class CheckBoxNodeTreeSample {
public static void main(String args[]) {
JFrame frame = new JFrame("CheckBox Tree");
CheckBoxNode accessibilityOptions[] = {
new CheckBoxNode(
"Move system caret with focus/selection changes", false),
new CheckBoxNode("Always expand alt text for images", true) };
CheckBoxNode browsingOptions[] = {
new CheckBoxNode("Notify when downloads complete", true),
new CheckBoxNode("Disable script debugging", true),
new CheckBoxNode("Use AutoComplete", true),
new CheckBoxNode("Browse in a new process", false) };
Vector accessVector = new NamedVector("Accessibility",
accessibilityOptions);
Vector browseVector = new NamedVector("Browsing", browsingOptions);
Object rootNodes[] = { accessVector, browseVector };
Vector rootVector = new NamedVector("Root", rootNodes);
JTree tree = new JTree(rootVector);
CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();
tree.setCellRenderer(renderer);
tree.setCellEditor(new CheckBoxNodeEditor(tree));
tree.setEditable(true);
JScrollPane scrollPane = new JScrollPane(tree);
frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
frame.setSize(300, 150);
frame.setVisible(true);
}
}
class CheckBoxNodeRenderer implements TreeCellRenderer {
private JCheckBox leafRenderer = new JCheckBox();
private DefaultTreeCellRenderer nonLeafRenderer = new DefaultTreeCellRenderer();
Color selectionBorderColor, selectionForeground, selectionBackground,
textForeground, textBackground;
protected JCheckBox getLeafRenderer() {
return leafRenderer;
}
public CheckBoxNodeRenderer() {
Font fontValue;
fontValue = UIManager.getFont("Tree.font");
if (fontValue != null) {
leafRenderer.setFont(fontValue);
}
Boolean booleanValue = (Boolean) UIManager
.get("Tree.drawsFocusBorderAroundIcon");
leafRenderer.setFocusPainted((booleanValue != null)
&& (booleanValue.booleanValue()));
selectionBorderColor = UIManager.getColor("Tree.selectionBorderColor");
selectionForeground = UIManager.getColor("Tree.selectionForeground");
selectionBackground = UIManager.getColor("Tree.selectionBackground");
textForeground = UIManager.getColor("Tree.textForeground");
textBackground = UIManager.getColor("Tree.textBackground");
}
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row,
boolean hasFocus) {
Component returnValue;
if (leaf) {
String stringValue = tree.convertValueToText(value, selected,
expanded, leaf, row, false);
leafRenderer.setText(stringValue);
leafRenderer.setSelected(false);
leafRenderer.setEnabled(tree.isEnabled());
if (selected) {
leafRenderer.setForeground(selectionForeground);
leafRenderer.setBackground(selectionBackground);
} else {
leafRenderer.setForeground(textForeground);
leafRenderer.setBackground(textBackground);
}
if ((value != null) && (value instanceof DefaultMutableTreeNode)) {
Object userObject = ((DefaultMutableTreeNode) value)
.getUserObject();
if (userObject instanceof CheckBoxNode) {
CheckBoxNode node = (CheckBoxNode) userObject;
leafRenderer.setText(node.getText());
leafRenderer.setSelected(node.isSelected());
}
}
returnValue = leafRenderer;
} else {
returnValue = nonLeafRenderer.getTreeCellRendererComponent(tree,
value, selected, expanded, leaf, row, hasFocus);
}
return returnValue;
}
}
class CheckBoxNodeEditor extends AbstractCellEditor implements TreeCellEditor {
CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();
ChangeEvent changeEvent = null;
JTree tree;
public CheckBoxNodeEditor(JTree tree) {
this.tree = tree;
}
public Object getCellEditorValue() {
JCheckBox checkbox = renderer.getLeafRenderer();
CheckBoxNode checkBoxNode = new CheckBoxNode(checkbox.getText(),
checkbox.isSelected());
return checkBoxNode;
}
public boolean isCellEditable(EventObject event) {
boolean returnValue = false;
if (event instanceof MouseEvent) {
MouseEvent mouseEvent = (MouseEvent) event;
TreePath path = tree.getPathForLocation(mouseEvent.getX(),
mouseEvent.getY());
if (path != null) {
Object node = path.getLastPathComponent();
if ((node != null) && (node instanceof DefaultMutableTreeNode)) {
DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node;
Object userObject = treeNode.getUserObject();
returnValue = ((treeNode.isLeaf()) && (userObject instanceof CheckBoxNode));
}
}
}
return returnValue;
}
public Component getTreeCellEditorComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row) {
Component editor = renderer.getTreeCellRendererComponent(tree, value,
true, expanded, leaf, row, true);
// editor always selected / focused
ItemListener itemListener = new ItemListener() {
public void itemStateChanged(ItemEvent itemEvent) {
if (stopCellEditing()) {
fireEditingStopped();
}
}
};
if (editor instanceof JCheckBox) {
((JCheckBox) editor).addItemListener(itemListener);
}
return editor;
}
}
class CheckBoxNode {
String text;
boolean selected;
public CheckBoxNode(String text, boolean selected) {
this.text = text;
this.selected = selected;
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean newValue) {
selected = newValue;
}
public String getText() {
return text;
}
public void setText(String newValue) {
text = newValue;
}
public String toString() {
return getClass().getName() + "[" + text + "/" + selected + "]";
}
}
class NamedVector extends Vector {
String name;
public NamedVector(String name) {
this.name = name;
}
public NamedVector(String name, Object elements[]) {
this.name = name;
for (int i = 0, n = elements.length; i < n; i++) {
add(elements[i]);
}
}
public String toString() {
return "[" + name + "]";
}
}
Combobox Tree Node Editor
import java.awt.BorderLayout;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeCellEditor;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellEditor;
public class ComboTreeSample {
public static void main(String args[]) {
JFrame frame = new JFrame("Editable Tree");
JTree tree = new JTree();
tree.setEditable(true);
DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) tree
.getCellRenderer();
String elements[] = { "Root", "chartreuse", "rugby", "sushi" };
JComboBox comboBox = new JComboBox(elements);
comboBox.setEditable(true);
TreeCellEditor comboEditor = new DefaultCellEditor(comboBox);
TreeCellEditor editor = new DefaultTreeCellEditor(tree, renderer,
comboEditor);
tree.setCellEditor(editor);
JScrollPane scrollPane = new JScrollPane(tree);
frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
frame.setSize(300, 150);
frame.setVisible(true);
}
}
extends DefaultTreeCellEditor to create Tree Leaf editor
import java.awt.BorderLayout;
import java.util.EventObject;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeCellEditor;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeNode;
public class EditLeafSample {
public static void main(String args[]) {
JFrame frame = new JFrame("Editable Tree");
JTree tree = new JTree();
tree.setEditable(true);
DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) tree
.getCellRenderer();
TreeCellEditor editor = new LeafCellEditor(tree, renderer);
tree.setCellEditor(editor);
JScrollPane scrollPane = new JScrollPane(tree);
frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
frame.setSize(300, 150);
frame.setVisible(true);
}
}
class LeafCellEditor extends DefaultTreeCellEditor {
public LeafCellEditor(JTree tree, DefaultTreeCellRenderer renderer) {
super(tree, renderer);
}
public LeafCellEditor(JTree tree, DefaultTreeCellRenderer renderer,
TreeCellEditor editor) {
super(tree, renderer, editor);
}
public boolean isCellEditable(EventObject event) {
boolean returnValue = super.isCellEditable(event);
if (returnValue) {
Object node = tree.getLastSelectedPathComponent();
if ((node != null) && (node instanceof TreeNode)) {
TreeNode treeNode = (TreeNode) node;
returnValue = treeNode.isLeaf();
}
}
return returnValue;
}
}
Scrollable Table Cell Renderer
/*
This library 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.
*/
import java.awt.Color;
import java.awt.ruponent;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.Scrollable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.table.TableCellRenderer;
/**
A <tt>TableCellRenderer</tt> which is based on an <tt>ExtendedJLabel</tt> rather than
a <tt>JLabel</tt> like the <tt>javax.swing.table.DefaultTableCellRenderer</tt>.
@author
@version $Revision: 1.4 $ $Date: 2003/08/18 07:48:28 $
*/
public class ExtendedTableCellRenderer extends ExtendedJLabel
implements TableCellRenderer {
private static final Border NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1);
private Color unselectedForeground;
private Color unselectedBackground;
/**
* Constructor.
*/
public ExtendedTableCellRenderer() {
super();
setOpaque(true);
setBorder(NO_FOCUS_BORDER);
}
public void setForeground(Color c) {
super.setForeground(c);
unselectedForeground = c;
}
public void setBackground(Color c) {
super.setBackground(c);
unselectedBackground = c;
}
public void updateUI() {
super.updateUI();
setForeground(null);
setBackground(null);
}
public Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column)
{
if (isSelected) {
super.setForeground(table.getSelectionForeground());
super.setBackground(table.getSelectionBackground());
} else {
super.setForeground((unselectedForeground != null) ? unselectedForeground : table.getForeground());
super.setBackground((unselectedBackground != null) ? unselectedBackground : table.getBackground());
}
setFont(table.getFont());
if (hasFocus) {
setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
if (table.isCellEditable(row, column)) {
super.setForeground(UIManager.getColor("Table.focusCellForeground"));
super.setBackground(UIManager.getColor("Table.focusCellBackground"));
}
} else {
setBorder(NO_FOCUS_BORDER);
}
setValue(value);
Color background = getBackground();
boolean colorMatch = (background != null) && (background.equals(table.getBackground())) && table.isOpaque();
setOpaque(!colorMatch);
return this;
}
public void validate() {}
public void revalidate() {}
public void repaint(long tm, int x, int y, int width, int height) {}
public void repaint(Rectangle r) { }
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
if (propertyName == "text") {
super.firePropertyChange(propertyName, oldValue, newValue);
}
}
public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) { }
private void setValue(Object value) {
setText((value == null) ? "" : value.toString());
}
}
/*
This library 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.
*/
class ExtendedJLabel extends JLabel implements Scrollable {
private boolean underlined = false;
private boolean autoTooltip = false;
/**
Constructor.
*/
public ExtendedJLabel() {
}
/**
Constructor.
@param text the label text.
*/
public ExtendedJLabel(String text) {
super(text);
}
public Dimension getPreferredScrollableViewportSize() {
return getSize();
}
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return getWidth() / 10;
}
public boolean getScrollableTracksViewportWidth() {
return false;
}
public boolean getScrollableTracksViewportHeight() {
return false;
}
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return 10;
}
/**
Check whether this label is underlined.
@return underlined or not
*/
public boolean isUnderlined() {
return underlined;
}
/**
Set whether this label is underlined.
@param underlined underlined or not
*/
public void setUnderlined(boolean underlined) {
this.underlined = underlined;
repaint();
}
/**
Check whether the tooltip text is automatically equal
to the text of this label or not.
@return equal or not
*/
public boolean getAutoTooltip() {
return autoTooltip;
}
/**
Set whether the tooltip text is automatically equal
to the text of this label or not.
@param autoTooltip equal or not
*/
public void setAutoTooltip(boolean autoTooltip) {
this.autoTooltip = autoTooltip;
setToolTipText(getText());
}
public void setText(String text) {
super.setText(text);
if (autoTooltip) {
setToolTipText(text);
}
}
/**
Convenience method for calling <tt>setText()</tt> with a <tt>short</tt>.
@param number the <tt>short</tt>
*/
public void setText(short number) {
setText(String.valueOf(number));
}
/**
Convenience method for calling <tt>setText()</tt> with a <tt>int</tt>.
@param number the <tt>int</tt>
*/
public void setText(int number) {
setText(String.valueOf(number));
}
/**
Convenience method for calling <tt>setText()</tt> with a <tt>double</tt>.
@param number the <tt>double</tt>
*/
public void setText(double number) {
setText(String.valueOf(number));
}
/**
Convenience method for calling <tt>setText()</tt> with a <tt>float</tt>.
@param number the <tt>float</tt>
*/
public void setText(float number) {
setText(String.valueOf(number));
}
/**
Convenience method for calling <tt>setText()</tt> with a <tt>long</tt>.
@param number the <tt>long</tt>
*/
public void setText(long number) {
setText(String.valueOf(number));
}
public void paint(Graphics g) {
super.paint(g);
if (underlined) {
Insets i = getInsets();
FontMetrics fm = g.getFontMetrics();
Rectangle textRect = new Rectangle();
Rectangle viewRect = new Rectangle(i.left, i.top, getWidth() - (i.right + i.left), getHeight() - (i.bottom + i.top) );
SwingUtilities.layoutCompoundLabel(
this,
fm,
getText(),
getIcon(),
getVerticalAlignment(),
getHorizontalAlignment(),
getVerticalTextPosition(),
getHorizontalTextPosition(),
viewRect,
new Rectangle(),
textRect,
getText() == null ? 0 : ((Integer)UIManager.get("Button.textIconGap")).intValue()
);
int offset = 2;
if (UIManager.getLookAndFeel().isNativeLookAndFeel() && System.getProperty("os.name").startsWith("Windows")) {
offset = 1;
}
g.fillRect(textRect.x + ((Integer)UIManager.get("Button.textShiftOffset")).intValue() ,
textRect.y + fm.getAscent() + ((Integer)UIManager.get("Button.textShiftOffset")).intValue() + offset,
textRect.width,
1);
}
}
}
Tree Cell Renderer
/*
Definitive Guide to Swing for Java 2, Second Edition
By John Zukowski
ISBN: 1-893115-78-X
Publisher: APress
*/
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ruponent;
import java.awt.GridLayout;
import java.util.Vector;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellRenderer;
public class BookTree {
public static void main(String args[]) {
JFrame frame = new JFrame("Book Tree");
Book javaBooks[] = {
new Book("Core Java 2 Fundamentals", "Cornell/Horstmann",
42.99f),
new Book("Taming Java Threads", "Holub", 34.95f),
new Book("JavaServer Pages", "Pekowsky", 39.95f) };
Book htmlBooks[] = { new Book("Dynamic HTML", "Goodman", 39.95f),
new Book("HTML 4 Bible", "Pfaffenberger/Gutzman", 49.99f) };
Vector javaVector = new NamedVector("Java Books", javaBooks);
Vector htmlVector = new NamedVector("HTML Books", htmlBooks);
Object rootNodes[] = { javaVector, htmlVector };
Vector rootVector = new NamedVector("Root", rootNodes);
JTree tree = new JTree(rootVector);
TreeCellRenderer renderer = new BookCellRenderer();
tree.setCellRenderer(renderer);
JScrollPane scrollPane = new JScrollPane(tree);
frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
frame.setSize(300, 300);
frame.setVisible(true);
}
}
class Book {
String title;
String authors;
float price;
public Book(String title, String authors, float price) {
this.title = title;
this.authors = authors;
this.price = price;
}
public String getTitle() {
return title;
}
public String getAuthors() {
return authors;
}
public float getPrice() {
return price;
}
}
class BookCellRenderer implements TreeCellRenderer {
JLabel titleLabel;
JLabel authorsLabel;
JLabel priceLabel;
JPanel renderer;
DefaultTreeCellRenderer defaultRenderer = new DefaultTreeCellRenderer();
Color backgroundSelectionColor;
Color backgroundNonSelectionColor;
public BookCellRenderer() {
renderer = new JPanel(new GridLayout(0, 1));
titleLabel = new JLabel(" ");
titleLabel.setForeground(Color.blue);
renderer.add(titleLabel);
authorsLabel = new JLabel(" ");
authorsLabel.setForeground(Color.blue);
renderer.add(authorsLabel);
priceLabel = new JLabel(" ");
priceLabel.setHorizontalAlignment(JLabel.RIGHT);
priceLabel.setForeground(Color.red);
renderer.add(priceLabel);
renderer.setBorder(BorderFactory.createLineBorder(Color.black));
backgroundSelectionColor = defaultRenderer
.getBackgroundSelectionColor();
backgroundNonSelectionColor = defaultRenderer
.getBackgroundNonSelectionColor();
}
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row,
boolean hasFocus) {
Component returnValue = null;
if ((value != null) && (value instanceof DefaultMutableTreeNode)) {
Object userObject = ((DefaultMutableTreeNode) value)
.getUserObject();
if (userObject instanceof Book) {
Book book = (Book) userObject;
titleLabel.setText(book.getTitle());
authorsLabel.setText(book.getAuthors());
priceLabel.setText("" + book.getPrice());
if (selected) {
renderer.setBackground(backgroundSelectionColor);
} else {
renderer.setBackground(backgroundNonSelectionColor);
}
renderer.setEnabled(tree.isEnabled());
returnValue = renderer;
}
}
if (returnValue == null) {
returnValue = defaultRenderer.getTreeCellRendererComponent(tree,
value, selected, expanded, leaf, row, hasFocus);
}
return returnValue;
}
}
class NamedVector extends Vector {
String name;
public NamedVector(String name) {
this.name = name;
}
public NamedVector(String name, Object elements[]) {
this.name = name;
for (int i = 0, n = elements.length; i < n; i++) {
add(elements[i]);
}
}
public String toString() {
return "[" + name + "]";
}
}
Tree Changed Renderer
/*
Definitive Guide to Swing for Java 2, Second Edition
By John Zukowski
ISBN: 1-893115-78-X
Publisher: APress
*/
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeCellRenderer;
public class TreeChangedRenderer {
public static void main(String args[]) {
JFrame frame = new JFrame("Changed Renderer");
JTree tree = new JTree();
DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) tree
.getCellRenderer();
renderer.setFont(new Font("Dialog", Font.BOLD | Font.ITALIC, 32));
int rowHeight = tree.getRowHeight();
if (rowHeight <= 0) {
tree.setRowHeight(rowHeight - 1);
}
// Swap background colors
Color backgroundSelection = renderer.getBackgroundSelectionColor();
renderer.setBackgroundSelectionColor(renderer
.getBackgroundNonSelectionColor());
renderer.setBackgroundNonSelectionColor(backgroundSelection);
// Swap text colors
Color textSelection = renderer.getTextSelectionColor();
renderer.setTextSelectionColor(renderer.getTextNonSelectionColor());
renderer.setTextNonSelectionColor(textSelection);
JScrollPane scrollPane = new JScrollPane(tree);
frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
frame.setSize(300, 150);
frame.setVisible(true);
}
}
Using DefaultTreeCellRenderer
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
public class Main extends JFrame {
private JTree m_simpleTree;
private DefaultMutableTreeNode m_rootNode;
public Main() {
m_rootNode = new DefaultMutableTreeNode("A");
DefaultMutableTreeNode enggNode = new DefaultMutableTreeNode("B");
DefaultMutableTreeNode markNode = new DefaultMutableTreeNode("C");
DefaultMutableTreeNode hrNode = new DefaultMutableTreeNode("D");
m_rootNode.add(enggNode);
m_rootNode.add(markNode);
m_rootNode.add(hrNode);
m_simpleTree = new JTree(m_rootNode);
DefaultTreeCellRenderer cellRenderer = (DefaultTreeCellRenderer) m_simpleTree.getCellRenderer();
cellRenderer.setOpenIcon(new ImageIcon("open.gif"));
cellRenderer.setClosedIcon(new ImageIcon("closed.gif"));
cellRenderer.setLeafIcon(new ImageIcon("leaf.gif"));
cellRenderer.setBackgroundNonSelectionColor(new Color(255, 255, 221));
cellRenderer.setBackgroundSelectionColor(new Color(0, 0, 128));
cellRenderer.setBorderSelectionColor(Color.black);
cellRenderer.setTextSelectionColor(Color.white);
cellRenderer.setTextNonSelectionColor(Color.blue);
JScrollPane scrollPane = new JScrollPane(m_simpleTree);
add(scrollPane);
}
public static void main(String[] arg) {
Main m = new Main();
m.setVisible(true);
m.setSize(new Dimension(450, 300));
m.validate();
}
}