/*
This file is part of the software framework JStatCom,
a library for building applications for data based analysis.
Copyright (C) 2000-2005 Markus Kraetzig
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.jstatcom.project;
import java.awt.Cursor;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreePath;
import org.apache.log4j.Logger;
import com.jstatcom.component.StdMessages;
import com.jstatcom.component.TopFrameReference;
/**
* A JTree for project and module management. The state of the
* tree is saved in a settings file that is loaded at program startup of the
* TopFrame.
*
* @author Markus Kraetzig
*/
public final class ProjectTree extends JTree {
private static final Logger log = Logger.getLogger(ProjectTree.class);
private final static List projectList = new ArrayList();
/**
* Singleton instance.
*/
private static final ProjectTree INSTANCE = new ProjectTree();
private final DefaultMutableTreeNode ROOT = new DefaultMutableTreeNode(
"ROOT");
// tree model
private final DefaultTreeModel projectTreeModel = new DefaultTreeModel(ROOT);
/**
* Not to be invoked.
*
*/
private ProjectTree() {
// not to be invoked
setBorder(new EmptyBorder(3, 3, 0, 0));
setModel(projectTreeModel);
setRowHeight(18);
setRootVisible(false);
setCellRenderer(new ProjectTreeCellRenderer());
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent keyEvent) {
if (keyEvent.getKeyChar() == KeyEvent.VK_DELETE) {
deleteSelectedProjects();
return;
}
if (keyEvent.getKeyCode() == KeyEvent.VK_ENTER) {
TreePath treePath = getSelectionPath();
if (treePath == null)
return;
Object o = treePath.getLastPathComponent();
if (o instanceof ProjectTreeNode) {
ProjectTreeNode node = (ProjectTreeNode) o;
loadProjectForNode(node);
return;
}
if (o instanceof ModuleTreeNode) {
ModuleTreeNode node = (ModuleTreeNode) o;
node.doAction();
return;
}
}
}
});
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
TreePath treePath = getPathForLocation(e.getX(), e.getY());
if (treePath == null)
return;
Object o = treePath.getLastPathComponent();
if (o instanceof ProjectTreeNode) {
if (SwingUtilities.isRightMouseButton(e)) {
setSelectionPath(treePath);
ProjectTreeNode node = (ProjectTreeNode) o;
ProjectNodePopup popup = ProjectNodePopup.getInstance();
popup.pack();
popup.show(ProjectTree.this, e.getX(), e.getY());
popup.setCurrentNode(node);
} else if (e.getClickCount() == 2) {
ProjectTreeNode node = (ProjectTreeNode) o;
loadProjectForNode(node);
}
return;
}
if (o instanceof ModuleTreeNode) {
ModuleTreeNode node = (ModuleTreeNode) o;
node.doAction();
return;
}
}
});
}
/**
* Deletes all selected project nodes from the tree. It shows a dialog
* before which asks whether the project files should be deleted as well or
* whether the action should be cancelled.
*/
public void deleteSelectedProjects() {
if (getSelectionCount() == 0)
return;
TreePath[] treePath = getSelectionPaths();
boolean hasProjectNodes = false;
if (treePath.length > 0)
// check for project nodes
for (int i = 0; i < treePath.length; i++) {
Object o = treePath[i].getLastPathComponent();
if ((o instanceof ProjectTreeNode)) {
hasProjectNodes = true;
break;
}
}
if (!hasProjectNodes)
return;
String msg = "Removing selected projects.\nAlso delete project files?\n\n";
msg = msg
+ "YES - delete project and file\nNO - only remove project from list\nCANCEL - do nothing";
int status = JOptionPane.showConfirmDialog(TopFrameReference
.getTopFrameRef(), msg, "Remove Selected Projects",
JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (status == JOptionPane.CANCEL_OPTION)
return;
for (int i = 0; i < treePath.length; i++) {
Object o = treePath[i].getLastPathComponent();
if ((o instanceof ProjectTreeNode)) {
ProjectTreeNode node = (ProjectTreeNode) o;
projectTreeModel.removeNodeFromParent(node);
projectList.remove(node);
if (status == JOptionPane.YES_OPTION)
node.getProjectFile().delete();
}
}
}
/**
* Loads a project from a project tree node. Invoked on double mouse click
* over project nodes.
*
* @param node
* the selected node
*/
public void loadProjectForNode(ProjectTreeNode node) {
// if (node.isCurrentProject())
// return;
try {
ProjectTree.this.setCursor(new Cursor(Cursor.WAIT_CURSOR));
ProjectManager.getInstance().deSerializeProject(
node.getProjectFile());
selectNode(node);
repaint();
} catch (Throwable ex) {
String msg = "There was an error loading a project from file:\n\""
+ node.getProjectFile().getAbsolutePath() + "\".";
log.error(msg, ex);
StdMessages.error(msg + "\nThe error message was:\n\""
+ ex.getMessage()
+ "\"\nPlease see the log for more details.",
"Project Load Error");
} finally {
ProjectTree.this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
}
/**
* Gets singleton instance of this tree.
*
* @return instance
*/
public static ProjectTree getInstance() {
return INSTANCE;
}
protected void selectNode(ProjectTreeNode node) {
for (int i = 0; i < projectList.size(); i++)
projectList.get(i).setCurrentProject(false);
if (node != null)
node.setCurrentProject(true);
}
/**
* Gets an iterator over all project nodes.
*
* @return iterator
*/
Iterator getProjectNodesIterator() {
return projectList.iterator();
}
/**
* Removes a tree node from the tree. Nothing is done if node
* is not a child anymore or if it is null.
*
* @param node
* reference to the node to be removed
*/
public void removeTreeNode(MutableTreeNode node) {
if (node == null)
return;
projectTreeModel.removeNodeFromParent(node);
projectList.remove(node);
}
/**
* Adds a node to this tree that represents a module.
*
* @param node
* a module node
* @throws IllegalArgumentException
* if (node == null)
*/
public void addModuleNode(ModuleTreeNode node) {
if (node == null)
throw new IllegalArgumentException("Argument was null.");
boolean inserted = false;
for (int i = 0; i < ROOT.getChildCount(); i++) {
Object item = ROOT.getChildAt(i);
if (item instanceof ModuleTreeNode) {
ModuleTreeNode mNode = (ModuleTreeNode) item;
if (mNode.getName().compareTo(node.getName()) >= 0) {
ROOT.insert(node, i);
inserted = true;
break;
}
} else {
ROOT.insert(node, i);
inserted = true;
break;
}
}
if (!inserted)
ROOT.add(node);
projectTreeModel.reload();
}
/**
* Adds a project node to this tree.
*
* @param node
* the element to add to the tree
* @throws IllegalArgumentException
* if (node == null)
*/
public void addProjectNode(ProjectTreeNode node) {
if (node == null)
throw new IllegalArgumentException("Argument was null.");
// if already there, set to current project
if (projectList.contains(node)) {
int i = projectList.indexOf(node);
ProjectTreeNode containedNode = projectList.get(i);
containedNode.setNode(node);
if (node.isCurrentProject())
selectNode(containedNode);
repaint();
return;
}
if (node.isCurrentProject())
selectNode(node);
// add sorted according to name
boolean inserted = false;
for (int i = 0; i < ROOT.getChildCount(); i++) {
Object item = ROOT.getChildAt(i);
if (item instanceof ProjectTreeNode) {
ProjectTreeNode pNode = (ProjectTreeNode) item;
if (pNode.getName().compareToIgnoreCase(node.getName()) >= 0
&& !pNode.isLastState()) {
ROOT.insert(node, i);
inserted = true;
break;
}
}
}
// node was not yet added
if (!inserted)
ROOT.add(node);
projectList.add(node);
projectTreeModel.reload();
}
}
Ads help maintain this website.