View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2024 the original author or authors.
4   //
5   // This library is free software; you can redistribute it and/or
6   // modify it under the terms of the GNU Lesser General Public
7   // License as published by the Free Software Foundation; either
8   // version 2.1 of the License, or (at your option) any later version.
9   //
10  // This library is distributed in the hope that it will be useful,
11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  // Lesser General Public License for more details.
14  //
15  // You should have received a copy of the GNU Lesser General Public
16  // License along with this library; if not, write to the Free Software
17  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  ///////////////////////////////////////////////////////////////////////////////////////////////
19  
20  package com.puppycrawl.tools.checkstyle.gui;
21  
22  import javax.swing.event.EventListenerList;
23  import javax.swing.event.TreeModelEvent;
24  import javax.swing.event.TreeModelListener;
25  import javax.swing.tree.TreeModel;
26  import javax.swing.tree.TreePath;
27  
28  import com.puppycrawl.tools.checkstyle.api.DetailAST;
29  import com.puppycrawl.tools.checkstyle.gui.MainFrameModel.ParseMode;
30  
31  /**
32   * The model that backs the parse tree in the GUI.
33   *
34   */
35  public class ParseTreeTableModel implements TreeModel {
36  
37      /** Presentation model. */
38      private final ParseTreeTablePresentation pModel;
39  
40      /**
41       * A list of event listeners for the tree model.
42       */
43      private final EventListenerList listenerList = new EventListenerList();
44  
45      /**
46       * Initialise pModel.
47       *
48       * @param parseTree DetailAST parse tree.
49       */
50      public ParseTreeTableModel(DetailAST parseTree) {
51          pModel = new ParseTreeTablePresentation(parseTree);
52          setParseTree(parseTree);
53      }
54  
55      /**
56       * Sets parse tree.
57       *
58       * @param parseTree DetailAST parse tree.
59       */
60      protected final void setParseTree(DetailAST parseTree) {
61          pModel.setRoot(parseTree);
62          final Object[] path = {pModel.getRoot()};
63          // no need to setup remaining info, as the call results in a
64          // table structure changed event anyway - we just pass nulls
65          fireTreeStructureChanged(this, path, null, (Object[]) null);
66      }
67  
68      /**
69       * Set parse mode.
70       *
71       * @param mode ParseMode enum
72       */
73      protected void setParseMode(ParseMode mode) {
74          pModel.setParseMode(mode);
75      }
76  
77      /**
78       * Returns number of available column.
79       *
80       * @return the number of available column.
81       */
82      public int getColumnCount() {
83          return pModel.getColumnCount();
84      }
85  
86      /**
87       * Returns column name of specified column number.
88       *
89       * @param column the column number
90       * @return the name for column number {@code column}.
91       */
92      public String getColumnName(int column) {
93          return pModel.getColumnName(column);
94      }
95  
96      /**
97       * Returns type of specified column number.
98       *
99       * @param column the column number
100      * @return the type for column number {@code column}.
101      */
102     // -@cs[ForbidWildcardAsReturnType] We need to satisfy javax.swing.table.AbstractTableModel
103     // public Class<?> getColumnClass(int columnIndex) {...}
104     public Class<?> getColumnClass(int column) {
105         return pModel.getColumnClass(column);
106     }
107 
108     /**
109      * Returns the value to be displayed for node at column number.
110      *
111      * @param node the node
112      * @param column the column number
113      * @return the value to be displayed for node {@code node},
114      *     at column number {@code column}.
115      */
116     public Object getValueAt(Object node, int column) {
117         return pModel.getValueAt(node, column);
118     }
119 
120     @Override
121     public Object getChild(Object parent, int index) {
122         return pModel.getChild(parent, index);
123     }
124 
125     @Override
126     public int getChildCount(Object parent) {
127         return pModel.getChildCount(parent);
128     }
129 
130     @Override
131     public void valueForPathChanged(TreePath path, Object newValue) {
132         // No Code, as tree is read-only
133     }
134 
135     @Override
136     public Object getRoot() {
137         return pModel.getRoot();
138     }
139 
140     @Override
141     public boolean isLeaf(Object node) {
142         return pModel.isLeaf(node);
143     }
144 
145     // This is not called in the JTree's default mode: use a naive implementation.
146     @Override
147     public int getIndexOfChild(Object parent, Object child) {
148         return pModel.getIndexOfChild(parent, child);
149     }
150 
151     @Override
152     public void addTreeModelListener(TreeModelListener listener) {
153         listenerList.add(TreeModelListener.class, listener);
154     }
155 
156     @Override
157     public void removeTreeModelListener(TreeModelListener listener) {
158         listenerList.remove(TreeModelListener.class, listener);
159     }
160 
161     /**
162      * Notify all listeners that have registered interest in
163      * 'tree structure changed' event.  The event instance
164      * is lazily created using the parameters passed into
165      * the fire method.
166      *
167      * @param source The Object responsible for generating the event.
168      * @param path An array of Object identifying the path to the parent of the modified items.
169      * @param childIndices An array of int that specifies the index values of the removed items.
170      * @param children An array of Object containing the inserted, removed, or changed objects.
171      * @see EventListenerList
172      */
173     private void fireTreeStructureChanged(Object source, Object[] path,
174                                   int[] childIndices,
175                                   Object... children) {
176         // Guaranteed to return a non-null array
177         final Object[] listeners = listenerList.getListenerList();
178         TreeModelEvent event = null;
179         // Process the listeners last to first, notifying
180         // those that are interested in this event
181         for (int i = listeners.length - 2; i >= 0; i -= 2) {
182             if (listeners[i] == TreeModelListener.class) {
183                 // Lazily create the event:
184                 if (event == null) {
185                     event = new TreeModelEvent(source, path,
186                         childIndices, children);
187                 }
188                 ((TreeModelListener) listeners[i + 1]).treeStructureChanged(event);
189             }
190         }
191     }
192 
193     /**
194      * Indicates whether the value for node {@code node},
195      * at column number {@code column} is editable.
196      *
197      * @param column the column number
198      * @return true if editable
199      */
200     public boolean isCellEditable(int column) {
201         return pModel.isCellEditable(column);
202     }
203 
204 }