//////////////////////////////////////////////////////////////////////////////// // checkstyle: Checks Java source code for adherence to a set of rules. // Copyright (C) 2001-2017 the original author or authors. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //////////////////////////////////////////////////////////////////////////////// package com.puppycrawl.tools.checkstyle.gui; import javax.swing.event.EventListenerList; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; import com.puppycrawl.tools.checkstyle.api.DetailAST; import com.puppycrawl.tools.checkstyle.gui.MainFrameModel.ParseMode; /** * The model that backs the parse tree in the GUI. * * @author Lars Kühne */ public class ParseTreeTableModel implements TreeModel { /** Presentation model. */ private final ParseTreeTablePresentation pModel; /** * A list of event listeners for the tree model. */ private final EventListenerList listenerList = new EventListenerList(); /** * @param parseTree DetailAST parse tree. */ public ParseTreeTableModel(DetailAST parseTree) { pModel = new ParseTreeTablePresentation(parseTree); setParseTree(parseTree); } /** * Sets parse tree. * @param parseTree DetailAST parse tree. */ protected final void setParseTree(DetailAST parseTree) { pModel.setParseTree(parseTree); final Object[] path = {pModel.getRoot()}; // no need to setup remaining info, as the call results in a // table structure changed event anyway - we just pass nulls fireTreeStructureChanged(this, path, null, (Object[]) null); } /** * Set parse mode. * @param mode ParseMode enum */ protected void setParseMode(ParseMode mode) { pModel.setParseMode(mode); } /** * @return the number of available column. */ public int getColumnCount() { return pModel.getColumnCount(); } /** * @param column the column number * @return the name for column number {@code column}. */ public String getColumnName(int column) { return pModel.getColumnName(column); } /** * @param column the column number * @return the type for column number {@code column}. */ // -@cs[ForbidWildcardAsReturnType] We need to satisfy javax.swing.table.AbstractTableModel // public Class<?> getColumnClass(int columnIndex) {...} public Class<?> getColumnClass(int column) { return pModel.getColumnClass(column); } /** * @param node the node * @param column the column number * @return the value to be displayed for node {@code node}, * at column number {@code column}. */ public Object getValueAt(Object node, int column) { return pModel.getValueAt(node, column); } @Override public Object getChild(Object parent, int index) { return pModel.getChild(parent, index); } @Override public int getChildCount(Object parent) { return pModel.getChildCount(parent); } @Override public void valueForPathChanged(TreePath path, Object newValue) { // No Code, as tree is read-only } @Override public Object getRoot() { return pModel.getRoot(); } @Override public boolean isLeaf(Object node) { return pModel.isLeaf(node); } // This is not called in the JTree's default mode: use a naive implementation. @Override public int getIndexOfChild(Object parent, Object child) { return pModel.getIndexOfChild(parent, child); } @Override public void addTreeModelListener(TreeModelListener listener) { listenerList.add(TreeModelListener.class, listener); } @Override public void removeTreeModelListener(TreeModelListener listener) { listenerList.remove(TreeModelListener.class, listener); } /** * Notify all listeners that have registered interest for * 'tree structure changed' event. The event instance * is lazily created using the parameters passed into * the fire method. * @param source The Object responsible for generating the event. * @param path An array of Object identifying the path to the parent of the modified items. * @param childIndices An array of int that specifies the index values of the removed items. * @param children An array of Object containing the inserted, removed, or changed objects. * @see EventListenerList */ private void fireTreeStructureChanged(Object source, Object[] path, int[] childIndices, Object... children) { // Guaranteed to return a non-null array final Object[] listeners = listenerList.getListenerList(); TreeModelEvent event = null; // Process the listeners last to first, notifying // those that are interested in this event for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == TreeModelListener.class) { // Lazily create the event: if (event == null) { event = new TreeModelEvent(source, path, childIndices, children); } ((TreeModelListener) listeners[i + 1]).treeStructureChanged(event); } } } /** * Indicates whether the the value for node {@code node}, * at column number {@code column} is editable. * * @param column the column number * @return true if editable */ public boolean isCellEditable(int column) { return pModel.isCellEditable(column); } }