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  import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
31  
32  /**
33   * The model that backs the parse tree in the GUI.
34   *
35   */
36  public class ParseTreeTableModel implements TreeModel {
37  
38      /** Presentation model. */
39      private final ParseTreeTablePresentation pModel;
40  
41      /**
42       * A list of event listeners for the tree model.
43       */
44      private final EventListenerList listenerList = new EventListenerList();
45  
46      /**
47       * Initialise pModel.
48       *
49       * @param parseTree DetailAST parse tree.
50       */
51      public ParseTreeTableModel(DetailAST parseTree) {
52          pModel = new ParseTreeTablePresentation(parseTree);
53          setParseTree(parseTree);
54      }
55  
56      /**
57       * Sets parse tree.
58       *
59       * @param parseTree DetailAST parse tree.
60       */
61      protected final void setParseTree(DetailAST parseTree) {
62          pModel.setRoot(parseTree);
63          final Object[] path = {pModel.getRoot()};
64          // no need to setup remaining info, as the call results in a
65          // table structure changed event anyway - we just pass nulls
66          fireTreeStructureChanged(this, path, null, CommonUtil.EMPTY_OBJECT_ARRAY);
67      }
68  
69      /**
70       * Set parse mode.
71       *
72       * @param mode ParseMode enum
73       */
74      protected void setParseMode(ParseMode mode) {
75          pModel.setParseMode(mode);
76      }
77  
78      /**
79       * Returns number of available column.
80       *
81       * @return the number of available column.
82       */
83      public int getColumnCount() {
84          return pModel.getColumnCount();
85      }
86  
87      /**
88       * Returns column name of specified column number.
89       *
90       * @param column the column number
91       * @return the name for column number {@code column}.
92       */
93      public String getColumnName(int column) {
94          return pModel.getColumnName(column);
95      }
96  
97      /**
98       * Returns type of specified column number.
99       *
100      * @param column the column number
101      * @return the type for column number {@code column}.
102      */
103     // -@cs[ForbidWildcardAsReturnType] We need to satisfy javax.swing.table.AbstractTableModel
104     // public Class<?> getColumnClass(int columnIndex) {...}
105     public Class<?> getColumnClass(int column) {
106         return pModel.getColumnClass(column);
107     }
108 
109     /**
110      * Returns the value to be displayed for node at column number.
111      *
112      * @param node the node
113      * @param column the column number
114      * @return the value to be displayed for node {@code node},
115      *     at column number {@code column}.
116      */
117     public Object getValueAt(Object node, int column) {
118         return pModel.getValueAt(node, column);
119     }
120 
121     @Override
122     public Object getChild(Object parent, int index) {
123         return pModel.getChild(parent, index);
124     }
125 
126     @Override
127     public int getChildCount(Object parent) {
128         return pModel.getChildCount(parent);
129     }
130 
131     @Override
132     public void valueForPathChanged(TreePath path, Object newValue) {
133         // No Code, as tree is read-only
134     }
135 
136     @Override
137     public Object getRoot() {
138         return pModel.getRoot();
139     }
140 
141     @Override
142     public boolean isLeaf(Object node) {
143         return pModel.isLeaf(node);
144     }
145 
146     // This is not called in the JTree's default mode: use a naive implementation.
147     @Override
148     public int getIndexOfChild(Object parent, Object child) {
149         return pModel.getIndexOfChild(parent, child);
150     }
151 
152     @Override
153     public void addTreeModelListener(TreeModelListener listener) {
154         listenerList.add(TreeModelListener.class, listener);
155     }
156 
157     @Override
158     public void removeTreeModelListener(TreeModelListener listener) {
159         listenerList.remove(TreeModelListener.class, listener);
160     }
161 
162     /**
163      * Notify all listeners that have registered interest in
164      * 'tree structure changed' event.  The event instance
165      * is lazily created using the parameters passed into
166      * the fire method.
167      *
168      * @param source The Object responsible for generating the event.
169      * @param path An array of Object identifying the path to the parent of the modified items.
170      * @param childIndices An array of int that specifies the index values of the removed items.
171      * @param children An array of Object containing the inserted, removed, or changed objects.
172      * @see EventListenerList
173      */
174     private void fireTreeStructureChanged(Object source, Object[] path,
175                                   int[] childIndices,
176                                   Object... children) {
177         // Guaranteed to return a non-null array
178         final Object[] listeners = listenerList.getListenerList();
179         TreeModelEvent event = null;
180         // Process the listeners last to first, notifying
181         // those that are interested in this event
182         for (int i = listeners.length - 2; i >= 0; i -= 2) {
183             if (listeners[i] == TreeModelListener.class) {
184                 // Lazily create the event:
185                 if (event == null) {
186                     event = new TreeModelEvent(source, path,
187                         childIndices, children);
188                 }
189                 ((TreeModelListener) listeners[i + 1]).treeStructureChanged(event);
190             }
191         }
192     }
193 
194     /**
195      * Indicates whether the value for node {@code node},
196      * at column number {@code column} is editable.
197      *
198      * @param column the column number
199      * @return true if editable
200      */
201     public boolean isCellEditable(int column) {
202         return pModel.isCellEditable(column);
203     }
204 
205 }