/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.util.viewer.gui;
import java.awt.BorderLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.util.viewer.gui.menu.ASTNodePopupMenu;
import net.sourceforge.pmd.util.viewer.model.ASTModel;
import net.sourceforge.pmd.util.viewer.model.ViewerModel;
import net.sourceforge.pmd.util.viewer.model.ViewerModelEvent;
import net.sourceforge.pmd.util.viewer.model.ViewerModelListener;
import net.sourceforge.pmd.util.viewer.util.NLS;
/**
* tree panel GUI
*
* @author Boris Gruschko ( boris at gruschko.org )
* @version $Id$
*/
public class ASTPanel extends JPanel implements ViewerModelListener, TreeSelectionListener {
private ViewerModel model;
private JTree tree;
/**
* constructs the panel
*
* @param model
* model to attach the panel to
*/
public ASTPanel(ViewerModel model) {
this.model = model;
init();
}
private void init() {
model.addViewerModelListener(this);
setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), NLS.nls("AST.PANEL.TITLE")));
setLayout(new BorderLayout());
tree = new JTree((TreeNode) null);
tree.addTreeSelectionListener(this);
tree.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
if (e.isPopupTrigger()) {
TreePath path = tree.getClosestPathForLocation(e.getX(), e.getY());
tree.setSelectionPath(path);
JPopupMenu menu = new ASTNodePopupMenu(model, (Node) path.getLastPathComponent());
menu.show(tree, e.getX(), e.getY());
}
}
});
add(new JScrollPane(tree), BorderLayout.CENTER);
}
/**
* @see ViewerModelListener#viewerModelChanged(ViewerModelEvent)
*/
@Override
public void viewerModelChanged(ViewerModelEvent e) {
switch (e.getReason()) {
case ViewerModelEvent.CODE_RECOMPILED:
tree.setModel(new ASTModel(model.getRootNode()));
break;
case ViewerModelEvent.NODE_SELECTED:
if (e.getSource() != this) {
List<Node> list = new ArrayList<>();
for (Node n = (Node) e.getParameter(); n != null; n = n.jjtGetParent()) {
list.add(n);
}
Collections.reverse(list);
TreePath path = new TreePath(list.toArray());
tree.setSelectionPath(path);
tree.scrollPathToVisible(path);
}
break;
default:
// Do nothing
break;
}
}
/**
* @see javax.swing.event.TreeSelectionListener#valueChanged(javax.swing.event.TreeSelectionEvent)
*/
@Override
public void valueChanged(TreeSelectionEvent e) {
model.selectNode((Node) e.getNewLeadSelectionPath().getLastPathComponent(), this);
}
}