custom tree node

来源:互联网 发布:阿里云栖大会苏州 编辑:程序博客网 时间:2024/06/16 09:48

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);
 }
}