001////////////////////////////////////////////////////////////////////////////////
002// checkstyle: Checks Java source code for adherence to a set of rules.
003// Copyright (C) 2001-2002  Oliver Burn
004//
005// This library is free software; you can redistribute it and/or
006// modify it under the terms of the GNU Lesser General Public
007// License as published by the Free Software Foundation; either
008// version 2.1 of the License, or (at your option) any later version.
009//
010// This library is distributed in the hope that it will be useful,
011// but WITHOUT ANY WARRANTY; without even the implied warranty of
012// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013// Lesser General Public License for more details.
014//
015// You should have received a copy of the GNU Lesser General Public
016// License along with this library; if not, write to the Free Software
017// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
018////////////////////////////////////////////////////////////////////////////////
019
020/*
021 * %W% %E%
022 *
023 * Copyright 1997, 1998 Sun Microsystems, Inc. All Rights Reserved.
024 *
025 * Redistribution and use in source and binary forms, with or
026 * without modification, are permitted provided that the following
027 * conditions are met:
028 *
029 * - Redistributions of source code must retain the above copyright
030 *   notice, this list of conditions and the following disclaimer.
031 *
032 * - Redistribution in binary form must reproduce the above
033 *   copyright notice, this list of conditions and the following
034 *   disclaimer in the documentation and/or other materials
035 *   provided with the distribution.
036 *
037 * Neither the name of Sun Microsystems, Inc. or the names of
038 * contributors may be used to endorse or promote products derived
039 * from this software without specific prior written permission.
040 *
041 * This software is provided "AS IS," without a warranty of any
042 * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
043 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
044 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
045 * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
046 * DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR
047 * RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE OR
048 * ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
049 * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
050 * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
051 * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
052 * THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS
053 * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
054 *
055 * You acknowledge that this software is not designed, licensed or
056 * intended for use in the design, construction, operation or
057 * maintenance of any nuclear facility.
058 */
059
060package com.puppycrawl.tools.checkstyle.gui;
061
062import javax.swing.JTree;
063import javax.swing.SwingUtilities;
064import javax.swing.table.AbstractTableModel;
065import javax.swing.tree.TreePath;
066import javax.swing.event.TreeExpansionEvent;
067import javax.swing.event.TreeExpansionListener;
068import javax.swing.event.TreeModelEvent;
069import javax.swing.event.TreeModelListener;
070
071/**
072 * This is a wrapper class takes a TreeTableModel and implements
073 * the table model interface. The implementation is trivial, with
074 * all of the event dispatching support provided by the superclass:
075 * the AbstractTableModel.
076 *
077 * <a href="http://java.sun.com/products/jfc/tsc/articles/treetable1/index.html">Original&nbsp;Source&nbsp;Location</a>
078 *
079 * @author Philip Milne
080 * @author Scott Violet
081 */
082public class TreeTableModelAdapter extends AbstractTableModel
083{
084    /** For Serialisation that will never happen. */
085    private static final long serialVersionUID = 8269213416115369275L;
086    private final JTree mTree;
087    private final TreeTableModel mTreeTableModel;
088
089    public TreeTableModelAdapter(TreeTableModel aTreeTableModel, JTree aTree)
090    {
091        this.mTree = aTree;
092        this.mTreeTableModel = aTreeTableModel;
093
094        aTree.addTreeExpansionListener(new TreeExpansionListener()
095        {
096            // Don't use fireTableRowsInserted() here; the selection model
097            // would get updated twice.
098            public void treeExpanded(TreeExpansionEvent event)
099            {
100                fireTableDataChanged();
101            }
102
103            public void treeCollapsed(TreeExpansionEvent event)
104            {
105                fireTableDataChanged();
106            }
107        });
108
109        // Install a TreeModelListener that can update the table when
110        // mTree changes. We use delayedFireTableDataChanged as we can
111        // not be guaranteed the mTree will have finished processing
112        // the event before us.
113        aTreeTableModel.addTreeModelListener(new TreeModelListener()
114        {
115            public void treeNodesChanged(TreeModelEvent e)
116            {
117                delayedFireTableDataChanged();
118            }
119
120            public void treeNodesInserted(TreeModelEvent e)
121            {
122                delayedFireTableDataChanged();
123            }
124
125            public void treeNodesRemoved(TreeModelEvent e)
126            {
127                delayedFireTableDataChanged();
128            }
129
130            public void treeStructureChanged(TreeModelEvent e)
131            {
132                delayedFireTableDataChanged();
133            }
134        });
135    }
136
137    // Wrappers, implementing TableModel interface.
138
139    public int getColumnCount()
140    {
141        return mTreeTableModel.getColumnCount();
142    }
143
144    /**
145     * {@inheritDoc}
146     */
147    @Override
148    public String getColumnName(int column)
149    {
150        return mTreeTableModel.getColumnName(column);
151    }
152
153    /**
154     * {@inheritDoc}
155     */
156    @Override
157    public Class<?> getColumnClass(int column)
158    {
159        return mTreeTableModel.getColumnClass(column);
160    }
161
162    public int getRowCount()
163    {
164        return mTree.getRowCount();
165    }
166
167    protected Object nodeForRow(int row)
168    {
169        final TreePath treePath = mTree.getPathForRow(row);
170        return treePath.getLastPathComponent();
171    }
172
173    public Object getValueAt(int row, int column)
174    {
175        return mTreeTableModel.getValueAt(nodeForRow(row), column);
176    }
177
178    /**
179     * {@inheritDoc}
180     */
181    @Override
182    public boolean isCellEditable(int row, int column)
183    {
184        return mTreeTableModel.isCellEditable(nodeForRow(row), column);
185    }
186
187    /**
188     * {@inheritDoc}
189     */
190    @Override
191    public void setValueAt(Object value, int row, int column)
192    {
193        mTreeTableModel.setValueAt(value, nodeForRow(row), column);
194    }
195
196    /**
197     * Invokes fireTableDataChanged after all the pending events have been
198     * processed. SwingUtilities.invokeLater is used to handle this.
199     */
200    protected void delayedFireTableDataChanged()
201    {
202        SwingUtilities.invokeLater(new Runnable()
203        {
204            public void run()
205            {
206                fireTableDataChanged();
207            }
208        });
209    }
210}
211