// BlogBridge -- RSS feed reader, manager, and web based service // Copyright (C) 2002-2006 by R. Pito Salas // // This program 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. // // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along with this program; // if not, write to the Free Software Foundation, Inc., 59 Temple Place, // Suite 330, Boston, MA 02111-1307 USA // // Contact: R. Pito Salas // mailto:pitosalas@users.sourceforge.net // More information: about BlogBridge // http://www.blogbridge.com // http://sourceforge.net/projects/blogbridge // // $Id $ // package com.salas.bb.utils.feedscollections; import com.jgoodies.forms.layout.CellConstraints; import com.jgoodies.forms.layout.FormLayout; import com.salas.bb.views.stylesheets.IStylesheet; import com.salas.bb.views.stylesheets.StylesheetManager; import com.salas.bb.views.stylesheets.domain.IRule; import javax.swing.*; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.TreePath; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; /** * Collections tree component. */ class CTree extends JTree { /** * Creates component. * * @param collection collection. * @param leafFolders <code>TRUE</code> if leaves should be considered as folders. */ public CTree(Collection collection, boolean leafFolders) { super(collection); setCellRenderer(new CTreeRenderer(StylesheetManager.getSuggestionsStylesheet(), leafFolders)); addMouseListener(new CTreeMouseListener()); setRootVisible(false); setShowsRootHandles(true); } /** * Check boxed list renderer. */ private static class CTreeRenderer extends DefaultTreeCellRenderer { private final JCheckBox box = new JCheckBox(); private final JPanel panel = new JPanel(); private final IStylesheet stylesheet; private final CellConstraints cc; private final boolean leafFolders; /** * Creates renderer. * * @param stylesheet the stylesheet. * @param leafFolders <code>TRUE</code> if leaves should be considered as folders. */ public CTreeRenderer(IStylesheet stylesheet, boolean leafFolders) { this.leafFolders = leafFolders; this.stylesheet = stylesheet; cc = new CellConstraints(); FormLayout layout = new FormLayout("p, 1dlu, p", "p"); panel.setLayout(layout); panel.add(this, cc.xy(3, 1)); box.setOpaque(false); panel.setOpaque(false); setLeafIcon(null); setClosedIcon(null); setOpenIcon(null); setIcon(null); } /** * Configures the renderer based on the passed in components. * The value is set from messaging the tree with * <code>convertValueToText</code>, which ultimately invokes * <code>toString</code> on <code>value</code>. * The foreground color is set based on the selection and the icon * is set based on on leaf and expanded. */ 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); CollectionNode node = (CollectionNode)value; String el = "folder"; String[] tags = node.getTags(); // Show box for items panel.remove(box); if (value instanceof CollectionItem) { panel.add(box, cc.xy(1, 1)); box.setSelected(node.isSelected()); if (!leafFolders) el = "item"; } IRule rule = getRule(el, tags); if (rule != null) { // Update font Font fnt = rule.getFont(); boolean bold = fnt != null && fnt.isBold(); Font curFont = getFont(); if (curFont.isBold() != bold) setFont(curFont.deriveFont(bold ? Font.BOLD : Font.PLAIN)); // Update color if (!sel) { Color color = rule.getColor(); if (color == null) color = Color.BLACK; setForeground(color); } // Assign icon Icon icon = rule.getIcon(); setIcon(icon); setClosedIcon(icon); setOpenIcon(icon); setLeafIcon(icon); } panel.invalidate(); return panel; } /** * Returns the rule from the stylesheet corresponding to the given element and tags. * * @param el element. * @param tags tags. * * @return rule. */ private IRule getRule(String el, String[] tags) { // NOTE: to further improve the performance (?) we can save the rules we get // in some cache return stylesheet.getRule(el, tags); } } private static class CTreeMouseListener extends MouseAdapter { private static int checkboxWidth = new JCheckBox().getPreferredSize().width; /** * Invoked when a mouse button has been pressed on a component. */ public void mousePressed(MouseEvent e) { JTree tree = (JTree)e.getSource(); TreePath path = tree.getPathForLocation(e.getX(), e.getY()); if (path != null) { CollectionNode node = (CollectionNode)path.getLastPathComponent(); if (node instanceof CollectionItem && (e.getX() < tree.getPathBounds(path).x + checkboxWidth)) { node.setSelected(!node.isSelected()); tree.treeDidChange(); } } } } }