001    /*
002     *  Licensed under the Apache License, Version 2.0 (the "License");
003     *  you may not use this file except in compliance with the License.
004     *  You may obtain a copy of the License at
005     *
006     *      http://www.apache.org/licenses/LICENSE-2.0
007     *
008     *  Unless required by applicable law or agreed to in writing, software
009     *  distributed under the License is distributed on an "AS IS" BASIS,
010     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011     *  See the License for the specific language governing permissions and
012     *  limitations under the License.
013     */
014    /*
015     * This file has been modified by Chris Pheby in accordance with Section 4.2
016     * of the Apache Software License
017     */
018    package org.jadira.dependencynavigator.gui;
019    
020    import java.awt.Color;
021    import java.awt.Component;
022    import java.awt.Dimension;
023    import java.awt.Font;
024    import java.awt.FontMetrics;
025    
026    import javax.swing.BorderFactory;
027    import javax.swing.JTree;
028    import javax.swing.tree.DefaultTreeCellRenderer;
029    
030    import org.jadira.dependencynavigator.model.Artifact;
031    
032    public class DependencyTreeRenderer extends DefaultTreeCellRenderer {
033    
034        private static final long serialVersionUID = -4604073586040441112L;
035    
036        @Override
037        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
038            DefaultTreeCellRenderer r = (DefaultTreeCellRenderer) super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
039            Artifact artifact = (Artifact) value;
040            r.setForeground(Color.BLACK);
041            r.setBackground(Color.WHITE);
042            r.setOpaque(true);
043            if (selected) {
044                r.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
045            } else {
046                r.setBorder(null);
047            }
048            if (Artifact.SELECTED_NONE == artifact.getSelected()) {
049                r.setFont(r.getFont().deriveFont(Font.PLAIN));
050            } else {
051                r.setFont(r.getFont().deriveFont(Font.BOLD));
052                if (Artifact.SELECTED_PRINCIPLE == artifact.getSelected()) {
053                    r.setBackground(Color.YELLOW);
054                }
055            }
056            return r;
057        }
058    
059        /**
060         * Add this override to recalculate the width of this JLabel. The super class default behaviour miscalculates the
061         * width, and so the '...' can appear. Instead, we 'simulate' the FontMetrics' stringWidth() method, by using
062         * charWidth(), plus some initialization and padding
063         */
064        @Override
065        public Dimension getPreferredSize() {
066            Dimension dim = super.getPreferredSize();
067            FontMetrics fm = getFontMetrics(getFont());
068            char[] chars = getText().toCharArray();
069            /*
070             * Initialize the width value to take into account any icons and gaps. Don't try to get the Icon's width
071             * programatically from within this method, as an infinite loop will result. I've just assumed a width of 16
072             * here, but you could (should?) save the actual value in getTreeCellRendererComponent() and retrieve it here,
073             * if you wanted.
074             */
075            int w = getIconTextGap() + 16;
076            for (int i = 0; i < chars.length; i++) {
077                w += fm.charWidth(chars[i]);
078            }
079            w += getText().length();
080            dim.width = w;
081            return dim;
082        }
083    }