package com.gordon.tree;
import java.awt.BorderLayout;import java.awt.Color;import java.awt.Component;import java.awt.Font;import java.awt.GradientPaint;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.Insets;import java.awt.RenderingHints;import java.awt.event.MouseEvent;import java.awt.event.MouseMotionAdapter;import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTree;import javax.swing.SwingUtilities;import javax.swing.UIManager;import javax.swing.border.Border;import javax.swing.tree.DefaultMutableTreeNode;import javax.swing.tree.DefaultTreeCellRenderer;import javax.swing.tree.DefaultTreeModel;
import com.gordon.tree.CustomBorderDemo.GradientTitleBorder;
public class NodeRolloverDemo extends JPanel {
private JTree tree = new JTree();
private int mouseOverRow = -1;
/** * Demonstrates how to highlight a node in a tree when the mouse is over it. */ private NodeRolloverDemo() { setLayout(new BorderLayout()); JScrollPane scrollPane = new JScrollPane(tree); add(scrollPane, BorderLayout.CENTER);
tree.setModel(createModel()); tree.addMouseMotionListener(mouseOverListener); tree.setCellRenderer(renderer); }
/** * MouseMotionListener that listens for changes in the selected row and * calls repaint. */ private MouseMotionListener mouseOverListener = new MouseMotionAdapter() {
private int currentRow;
@Override public void mouseMoved(MouseEvent e) { currentRow = tree.getClosestRowForLocation(e.getX(), e.getY()); if (currentRow != mouseOverRow) { mouseOverRow = currentRow; repaint(); } } };
/** * Renderer the row that the mouse is over Yellow */ private DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer() { @Override public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
if (row == mouseOverRow) { setBackgroundNonSelectionColor(Color.YELLOW); this.setBorder(new GradientTitleBorder("", new Color(0x418EDC), new Color(0x6B91B8), Color.WHITE, 25)); } else { setBackgroundNonSelectionColor(UIManager .getColor("Tree.textBackground")); this.setBorder(null); }
return this; } };
/** * Custom border class, paints a titled border using a gradient. */ public class GradientTitleBorder implements Border {
private String title;
private int titleHeight;
private Insets insets = new Insets(titleHeight, 0, 0, 0);
private Color primaryColor;
private Color secondaryColor;
private Color fontColor;
private Color shadowColor;
private int indent = 5;
private Font titleFont;
/** * Constructtor that assumes a title height. * * @param title - * string to display * @param primaryColor - * first color of gradient * @param secondaryColor - * second color of gradient (lower) * @param fontColor - * color for the font */ public GradientTitleBorder(String title, Color primaryColor, Color secondaryColor, Color fontColor) { this(title, primaryColor, secondaryColor, fontColor, 30); }
/** * Full option constructor * * @param title - * string to display * @param primaryColor - * first color of gradient * @param secondaryColor - * second color of gradient (lower) * @param fontColor - * color for the font * @param titleHeight - * height of the title bar */ public GradientTitleBorder(String title, Color primaryColor, Color secondaryColor, Color fontColor, int titleHeight) { this.title = title; this.titleHeight = titleHeight; this.insets = new Insets(titleHeight, 2, 2, 2); this.primaryColor = primaryColor; this.shadowColor = primaryColor.darker(); this.secondaryColor = secondaryColor; this.fontColor = fontColor; this.titleFont = UIManager.getFont("TitledBorder.font").deriveFont( Font.BOLD); }
/** * Creates a GradientTitleBorder with default values. * * @param title */ public GradientTitleBorder(String title) { this(title, Color.BLACK, Color.GRAY, Color.WHITE, 30); }
/** * */ public Insets getBorderInsets(Component c) { return insets; }
/** * */ public boolean isBorderOpaque() { return false; }
/** * paint the border, being carefull to stay inside the insets. */ public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Graphics2D g2d = (Graphics2D) g; g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
GradientPaint gp = new GradientPaint(x, y, primaryColor, x, y + titleHeight, secondaryColor); g2d.setPaint(gp); g2d.fillRect(x, y, width, titleHeight);
g2d.setColor(shadowColor); g2d.drawRect(x, y - 49, width - 1, titleHeight);
g2d.setFont(titleFont);
g2d.setColor(shadowColor); int titleOffset = (titleHeight / 2) + (c.getFont().getSize() / 2) - 1;
g2d.drawString(title, x + insets.left + indent + 1, y + titleOffset + 1);
g2d.setColor(fontColor); g2d.drawString(title, x + insets.left + indent, y + titleOffset);
g2d.setColor(shadowColor); g2d.drawRect(x, y - 1, width - 1, height); } }
/** * Start the demo on the Event Dispatch Thread. * * @param args * the command line arguments */ public static void main(String[] args) {
// turn bold fonts off in metal UIManager.put("swing.boldMetal", Boolean.FALSE);
SwingUtilities.invokeLater(new Runnable() { public void run() { JFrame demoFrame = new JFrame(); demoFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); demoFrame.setContentPane(new NodeRolloverDemo()); demoFrame.pack(); demoFrame.setVisible(true); } }); }
/** * Creates the demos tree model which contains java books. * * @return the demos tree model */ private DefaultTreeModel createModel() { DefaultMutableTreeNode root = new DefaultMutableTreeNode("Books"); DefaultMutableTreeNode category = null; DefaultMutableTreeNode book = null;
category = new DefaultMutableTreeNode("Books for Java Programmers"); root.add(category);
// original Tutorial book = new DefaultMutableTreeNode( "The Java Tutorial: A Short Course on the Basics"); category.add(book);
// Tutorial Continued book = new DefaultMutableTreeNode( "The Java Tutorial Continued: The Rest of the JDK"); category.add(book);
// JFC Swing Tutorial book = new DefaultMutableTreeNode( "The JFC Swing Tutorial: A Guide to Constructing GUIs"); category.add(book);
// Bloch book = new DefaultMutableTreeNode( "Effective Java Programming Language Guide"); category.add(book);
// Arnold/Gosling book = new DefaultMutableTreeNode("The Java Programming Language"); category.add(book);
// Chan book = new DefaultMutableTreeNode("The Java Developers Almanac"); category.add(book);
category = new DefaultMutableTreeNode("Books for Java Implementers"); root.add(category);
// VM book = new DefaultMutableTreeNode( "The Java Virtual Machine Specification"); category.add(book);
// Language Spec book = new DefaultMutableTreeNode("The Java Language Specification"); category.add(book); return new DefaultTreeModel(root); }}