0N/A/*
2362N/A * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage javax.swing.plaf.metal;
0N/A
0N/Aimport javax.swing.*;
0N/Aimport javax.swing.event.*;
0N/Aimport java.awt.*;
0N/Aimport java.awt.event.*;
0N/Aimport java.beans.*;
0N/Aimport java.io.*;
0N/Aimport java.util.*;
0N/Aimport javax.swing.plaf.*;
0N/Aimport javax.swing.tree.*;
0N/A
0N/Aimport javax.swing.plaf.basic.*;
0N/A
0N/A/**
0N/A * The metal look and feel implementation of <code>TreeUI</code>.
0N/A * <p>
0N/A * <code>MetalTreeUI</code> allows for configuring how to
0N/A * visually render the spacing and delineation between nodes. The following
0N/A * hints are supported:
0N/A *
0N/A * <table summary="Descriptions of supported hints: Angled, Horizontal, and None">
0N/A * <tr>
0N/A * <th><p align="left">Angled</p></th>
0N/A * <td>A line is drawn connecting the child to the parent. For handling
0N/A * of the root node refer to
0N/A * {@link javax.swing.JTree#setRootVisible} and
0N/A * {@link javax.swing.JTree#setShowsRootHandles}.
0N/A * </td>
0N/A * </tr>
0N/A * <tr>
0N/A * <th><p align="left">Horizontal</p></th>
0N/A * <td>A horizontal line is drawn dividing the children of the root node.</td>
0N/A * </tr>
0N/A * <tr>
0N/A * <th><p align="left">None</p></th>
0N/A * <td>Do not draw any visual indication between nodes.</td>
0N/A * </tr>
0N/A * </table>
0N/A *
0N/A * <p>
0N/A * As it is typically impratical to obtain the <code>TreeUI</code> from
0N/A * the <code>JTree</code> and cast to an instance of <code>MetalTreeUI</code>
0N/A * you enable this property via the client property
0N/A * <code>JTree.lineStyle</code>. For example, to switch to
0N/A * <code>Horizontal</code> style you would do:
0N/A * <code>tree.putClientProperty("JTree.lineStyle", "Horizontal");</code>
0N/A * <p>
0N/A * The default is <code>Angled</code>.
611N/A *
0N/A * @author Tom Santos
0N/A * @author Steve Wilson (value add stuff)
0N/A */
0N/Apublic class MetalTreeUI extends BasicTreeUI {
0N/A
0N/A private static Color lineColor;
0N/A
0N/A private static final String LINE_STYLE = "JTree.lineStyle";
0N/A
0N/A private static final String LEG_LINE_STYLE_STRING = "Angled";
0N/A private static final String HORIZ_STYLE_STRING = "Horizontal";
0N/A private static final String NO_STYLE_STRING = "None";
0N/A
0N/A private static final int LEG_LINE_STYLE = 2;
0N/A private static final int HORIZ_LINE_STYLE = 1;
0N/A private static final int NO_LINE_STYLE = 0;
0N/A
0N/A private int lineStyle = LEG_LINE_STYLE;
0N/A private PropertyChangeListener lineStyleListener = new LineListener();
0N/A
0N/A // Boilerplate
0N/A public static ComponentUI createUI(JComponent x) {
0N/A return new MetalTreeUI();
0N/A }
0N/A
0N/A public MetalTreeUI()
0N/A {
0N/A super();
0N/A }
0N/A
0N/A protected int getHorizontalLegBuffer()
0N/A {
0N/A return 3;
0N/A }
0N/A
0N/A public void installUI( JComponent c ) {
0N/A super.installUI( c );
0N/A lineColor = UIManager.getColor( "Tree.line" );
0N/A
0N/A Object lineStyleFlag = c.getClientProperty( LINE_STYLE );
0N/A decodeLineStyle(lineStyleFlag);
0N/A c.addPropertyChangeListener(lineStyleListener);
0N/A
0N/A }
0N/A
0N/A public void uninstallUI( JComponent c) {
0N/A c.removePropertyChangeListener(lineStyleListener);
0N/A super.uninstallUI(c);
0N/A }
0N/A
0N/A /** this function converts between the string passed into the client property
0N/A * and the internal representation (currently and int)
0N/A *
0N/A */
0N/A protected void decodeLineStyle(Object lineStyleFlag) {
0N/A if ( lineStyleFlag == null ||
0N/A lineStyleFlag.equals(LEG_LINE_STYLE_STRING)){
0N/A lineStyle = LEG_LINE_STYLE; // default case
0N/A } else {
0N/A if ( lineStyleFlag.equals(NO_STYLE_STRING) ) {
0N/A lineStyle = NO_LINE_STYLE;
0N/A } else if ( lineStyleFlag.equals(HORIZ_STYLE_STRING) ) {
0N/A lineStyle = HORIZ_LINE_STYLE;
0N/A }
0N/A }
0N/A
0N/A }
0N/A
0N/A protected boolean isLocationInExpandControl(int row, int rowLevel,
0N/A int mouseX, int mouseY) {
0N/A if(tree != null && !isLeaf(row)) {
0N/A int boxWidth;
0N/A
0N/A if(getExpandedIcon() != null)
0N/A boxWidth = getExpandedIcon().getIconWidth() + 6;
611N/A else
0N/A boxWidth = 8;
611N/A
0N/A Insets i = tree.getInsets();
0N/A int boxLeftX = (i != null) ? i.left : 0;
0N/A
0N/A
0N/A boxLeftX += (((rowLevel + depthOffset - 1) * totalChildIndent) +
0N/A getLeftChildIndent()) - boxWidth/2;
0N/A
0N/A int boxRightX = boxLeftX + boxWidth;
0N/A
0N/A return mouseX >= boxLeftX && mouseX <= boxRightX;
0N/A }
0N/A return false;
0N/A }
0N/A
0N/A public void paint(Graphics g, JComponent c) {
0N/A super.paint( g, c );
0N/A
0N/A
0N/A // Paint the lines
0N/A if (lineStyle == HORIZ_LINE_STYLE && !largeModel) {
0N/A paintHorizontalSeparators(g,c);
0N/A }
611N/A }
0N/A
0N/A protected void paintHorizontalSeparators(Graphics g, JComponent c) {
0N/A g.setColor( lineColor );
0N/A
0N/A Rectangle clipBounds = g.getClipBounds();
0N/A
0N/A int beginRow = getRowForPath(tree, getClosestPathForLocation
0N/A (tree, 0, clipBounds.y));
0N/A int endRow = getRowForPath(tree, getClosestPathForLocation
0N/A (tree, 0, clipBounds.y + clipBounds.height - 1));
0N/A
0N/A if ( beginRow <= -1 || endRow <= -1 ) {
0N/A return;
0N/A }
0N/A
0N/A for ( int i = beginRow; i <= endRow; ++i ) {
0N/A TreePath path = getPathForRow(tree, i);
0N/A
0N/A if(path != null && path.getPathCount() == 2) {
0N/A Rectangle rowBounds = getPathBounds(tree,getPathForRow
0N/A (tree, i));
0N/A
0N/A // Draw a line at the top
0N/A if(rowBounds != null)
0N/A g.drawLine(clipBounds.x, rowBounds.y,
0N/A clipBounds.x + clipBounds.width, rowBounds.y);
0N/A }
0N/A }
0N/A
0N/A }
0N/A
0N/A protected void paintVerticalPartOfLeg(Graphics g, Rectangle clipBounds,
0N/A Insets insets, TreePath path) {
0N/A if (lineStyle == LEG_LINE_STYLE) {
0N/A super.paintVerticalPartOfLeg(g, clipBounds, insets, path);
611N/A }
0N/A }
0N/A
0N/A protected void paintHorizontalPartOfLeg(Graphics g, Rectangle clipBounds,
0N/A Insets insets, Rectangle bounds,
0N/A TreePath path, int row,
0N/A boolean isExpanded,
0N/A boolean hasBeenExpanded, boolean
0N/A isLeaf) {
0N/A if (lineStyle == LEG_LINE_STYLE) {
0N/A super.paintHorizontalPartOfLeg(g, clipBounds, insets, bounds,
0N/A path, row, isExpanded,
0N/A hasBeenExpanded, isLeaf);
0N/A }
0N/A }
0N/A
0N/A /** This class listens for changes in line style */
0N/A class LineListener implements PropertyChangeListener {
0N/A public void propertyChange(PropertyChangeEvent e) {
0N/A String name = e.getPropertyName();
0N/A if ( name.equals( LINE_STYLE ) ) {
0N/A decodeLineStyle(e.getNewValue());
0N/A }
0N/A }
0N/A } // end class PaletteListener
0N/A
0N/A}
0N/A