001    /* JAPI - (Yet another (hopefully) useful) Java API
002     *
003     * Copyright (C) 2004-2006 Christian Hujer
004     *
005     * This program is free software; you can redistribute it and/or
006     * modify it under the terms of the GNU General Public License as
007     * published by the Free Software Foundation; either version 2 of the
008     * License, or (at your option) any later version.
009     *
010     * This program is distributed in the hope that it will be useful, but
011     * WITHOUT ANY WARRANTY; without even the implied warranty of
012     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013     * General Public License for more details.
014     *
015     * You should have received a copy of the GNU General Public License
016     * along with this program; if not, write to the Free Software
017     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
018     * 02111-1307, USA.
019     */
020    
021    package net.sf.japi.swing.treetable;
022    
023    import javax.swing.event.EventListenerList;
024    import javax.swing.event.TreeModelEvent;
025    import javax.swing.event.TreeModelListener;
026    
027    /** Abstract base implementation of TreeTableModel.
028     * @author <a href="mailto:chris@riedquat.de">Christian Hujer</a>
029     */
030    public abstract class AbstractTreeTableModel<R, T> implements TreeTableModel<R, T> {
031    
032        /** The tree root node content object. */
033        private final R root;
034    
035        /** The Event listener list for registering TreeModelListeners. */
036        private final EventListenerList listenerList = new EventListenerList();
037    
038        /** Create an AbstractTreeTableModel.
039         * @param root tree root node content object
040         */
041        protected AbstractTreeTableModel(final R root) {
042            this.root = root;
043        }
044    
045        /** {@inheritDoc} */
046        public R getRoot() {
047            return root;
048        }
049    
050        /** {@inheritDoc} */
051        public boolean isLeaf(final T node) {
052            return getChildCount(node) == 0;
053        }
054    
055        /** {@inheritDoc} */
056        public int getIndexOfChild(final T parent, final T child) {
057            for (int i = 0; i < getChildCount(parent); i++) {
058                if (getChild(parent, i).equals(child)) {
059                    return i;
060                }
061            }
062            return -1;
063        }
064    
065        /** {@inheritDoc} */
066        public void addTreeModelListener(final TreeModelListener l) {
067            listenerList.add(TreeModelListener.class, l);
068        }
069    
070        /** {@inheritDoc} */
071        public void removeTreeModelListener(final TreeModelListener l) {
072            listenerList.remove(TreeModelListener.class, l);
073        }
074    
075        /** {@inheritDoc} */
076        public Class<?> getColumnClass(final int column) {
077            return Object.class;
078        }
079    
080       /** {@inheritDoc} */
081        public boolean isCellEditable(final T node, final int column) {
082           //noinspection ObjectEquality
083           return getColumnClass(column) == TreeTableModel.class;
084        }
085    
086        /** {@inheritDoc} */
087        public void setValueAt(final Object value, final T node, final int column) {
088            // The basic implementation does nothing
089        }
090    
091        /** Informs all registered listeners of a change.
092         * @param source
093         * @param path
094         * @param childIndices
095         * @param children
096         */
097        protected void fireTreeNodesChanged(final Object source, final T[] path, final int[] childIndices, final T[] children) {
098            final Object[] listeners = listenerList.getListenerList();
099            final TreeModelEvent e = new TreeModelEvent(source, path, childIndices, children);
100            for (int i = listeners.length - 2; i >= 0; i -= 2) {
101                //noinspection ObjectEquality
102                if (listeners[i] == TreeModelListener.class) {
103                    ((TreeModelListener)listeners[i+1]).treeNodesChanged(e);
104                }
105            }
106        }
107    
108        /** Informs all registered listeners of an insertion.
109         * @param source
110         * @param path
111         * @param childIndices
112         * @param children
113         */
114        protected void fireTreeNodesInserted(final Object source, final Object[] path, final int[] childIndices, final Object[] children) {
115            final Object[] listeners = listenerList.getListenerList();
116            final TreeModelEvent e = new TreeModelEvent(source, path, childIndices, children);
117            for (int i = listeners.length - 2; i >= 0; i -= 2) {
118                //noinspection ObjectEquality
119                if (listeners[i] == TreeModelListener.class) {
120                    ((TreeModelListener)listeners[i + 1]).treeNodesInserted(e);
121                }
122            }
123        }
124    
125        /** Informs all registered listeners of a removal.
126         * @param source
127         * @param path
128         * @param childIndices
129         * @param children
130         */
131        protected void fireTreeNodesRemoved(final Object source, final Object[] path, final int[] childIndices, final Object[] children) {
132            final Object[] listeners = listenerList.getListenerList();
133            final TreeModelEvent e = new TreeModelEvent(source, path, childIndices, children);
134            for (int i = listeners.length - 2; i >= 0; i -= 2) {
135                //noinspection ObjectEquality
136                if (listeners[i] == TreeModelListener.class) {
137                    ((TreeModelListener)listeners[i + 1]).treeNodesRemoved(e);
138                }
139            }
140        }
141    
142        /** Informs all registered listeners of a structural change.
143         * @param source
144         * @param path
145         * @param childIndices
146         * @param children
147         */
148        protected void fireTreeStructureChanged(final Object source, final Object[] path, final int[] childIndices, final Object[] children) {
149            final Object[] listeners = listenerList.getListenerList();
150            final TreeModelEvent e = new TreeModelEvent(source, path, childIndices, children);
151            for (int i = listeners.length - 2; i >= 0; i -= 2) {
152                //noinspection ObjectEquality
153                if (listeners[i] == TreeModelListener.class) {
154                    ((TreeModelListener)listeners[i + 1]).treeStructureChanged(e);
155                }
156            }
157        }
158    
159    } // class AbstractTreeTableModel