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 tree;
087    private final TreeTableModel treeTableModel;
088
089    public TreeTableModelAdapter(TreeTableModel treeTableModel, JTree tree)
090    {
091        this.tree = tree;
092        this.treeTableModel = treeTableModel;
093
094        tree.addTreeExpansionListener(new TreeExpansionListener()
095        {
096            // Don't use fireTableRowsInserted() here; the selection model
097            // would get updated twice.
098            @Override
099            public void treeExpanded(TreeExpansionEvent event)
100            {
101                fireTableDataChanged();
102            }
103
104            @Override
105            public void treeCollapsed(TreeExpansionEvent event)
106            {
107                fireTableDataChanged();
108            }
109        });
110
111        // Install a TreeModelListener that can update the table when
112        // mTree changes. We use delayedFireTableDataChanged as we can
113        // not be guaranteed the mTree will have finished processing
114        // the event before us.
115        treeTableModel.addTreeModelListener(new TreeModelListener()
116        {
117            @Override
118            public void treeNodesChanged(TreeModelEvent e)
119            {
120                delayedFireTableDataChanged();
121            }
122
123            @Override
124            public void treeNodesInserted(TreeModelEvent e)
125            {
126                delayedFireTableDataChanged();
127            }
128
129            @Override
130            public void treeNodesRemoved(TreeModelEvent e)
131            {
132                delayedFireTableDataChanged();
133            }
134
135            @Override
136            public void treeStructureChanged(TreeModelEvent e)
137            {
138                delayedFireTableDataChanged();
139            }
140        });
141    }
142
143    // Wrappers, implementing TableModel interface.
144
145    @Override
146    public int getColumnCount()
147    {
148        return treeTableModel.getColumnCount();
149    }
150
151    /**
152     * {@inheritDoc}
153     */
154    @Override
155    public String getColumnName(int column)
156    {
157        return treeTableModel.getColumnName(column);
158    }
159
160    /**
161     * {@inheritDoc}
162     */
163    @Override
164    public Class<?> getColumnClass(int column)
165    {
166        return treeTableModel.getColumnClass(column);
167    }
168
169    @Override
170    public int getRowCount()
171    {
172        return tree.getRowCount();
173    }
174
175    protected Object nodeForRow(int row)
176    {
177        final TreePath treePath = tree.getPathForRow(row);
178        return treePath.getLastPathComponent();
179    }
180
181    @Override
182    public Object getValueAt(int row, int column)
183    {
184        return treeTableModel.getValueAt(nodeForRow(row), column);
185    }
186
187    /**
188     * {@inheritDoc}
189     */
190    @Override
191    public boolean isCellEditable(int row, int column)
192    {
193        return treeTableModel.isCellEditable(nodeForRow(row), column);
194    }
195
196    /**
197     * {@inheritDoc}
198     */
199    @Override
200    public void setValueAt(Object value, int row, int column)
201    {
202        treeTableModel.setValueAt(value, nodeForRow(row), column);
203    }
204
205    /**
206     * Invokes fireTableDataChanged after all the pending events have been
207     * processed. SwingUtilities.invokeLater is used to handle this.
208     */
209    protected void delayedFireTableDataChanged()
210    {
211        SwingUtilities.invokeLater(new Runnable()
212        {
213            @Override
214            public void run()
215            {
216                fireTableDataChanged();
217            }
218        });
219    }
220}
221