/********************************************************************************
* *
* (c) Copyright 2010 Verizon Communications USA and The Open University UK *
* *
* This software is freely distributed in accordance with *
* the GNU Lesser General Public (LGPL) license, version 3 or later *
* as published by the Free Software Foundation. *
* For details see LGPL: http://www.fsf.org/licensing/licenses/lgpl.html *
* and GPL: http://www.fsf.org/licensing/licenses/gpl-3.0.html *
* *
* This software is provided by the copyright holders and contributors "as is" *
* and any express or implied warranties, including, but not limited to, the *
* implied warranties of merchantability and fitness for a particular purpose *
* are disclaimed. In no event shall the copyright owner or contributors be *
* liable for any direct, indirect, incidental, special, exemplary, or *
* consequential damages (including, but not limited to, procurement of *
* substitute goods or services; loss of use, data, or profits; or business *
* interruption) however caused and on any theory of liability, whether in *
* contract, strict liability, or tort (including negligence or otherwise) *
* arising in any way out of the use of this software, even if advised of the *
* possibility of such damage. *
* *
********************************************************************************/
package com.compendium.ui.tags;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceContext;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetContext;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Date;
import java.util.Enumeration;
import java.util.EventObject;
import java.util.Hashtable;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.swing.AbstractCellEditor;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.plaf.basic.BasicTreeUI;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.compendium.LanguageProperties;
import com.compendium.ProjectCompendium;
import com.compendium.core.CoreUtilities;
import com.compendium.core.ICoreConstants;
import com.compendium.core.datamodel.Code;
import com.compendium.core.datamodel.IModel;
import com.compendium.core.datamodel.NodePosition;
import com.compendium.core.datamodel.NodeSummary;
import com.compendium.core.datamodel.PCSession;
import com.compendium.core.datamodel.View;
import com.compendium.ui.FormatProperties;
import com.compendium.ui.IUIConstants;
import com.compendium.ui.ListTableModel;
import com.compendium.ui.ProjectCompendiumFrame;
import com.compendium.ui.TableSorter;
import com.compendium.ui.UIButton;
import com.compendium.ui.UIList;
import com.compendium.ui.UIListViewFrame;
import com.compendium.ui.UIMapViewFrame;
import com.compendium.ui.UINode;
import com.compendium.ui.UIUtilities;
import com.compendium.ui.UIViewFrame;
import com.compendium.ui.UIViewPane;
import com.compendium.ui.plaf.ViewPaneUI;
/**
* Draws the panel for assigning codes.
*
* @author Mohammed Sajid Ali / Michelle Bachler
*/
public class UITagTreePanel extends JPanel implements ActionListener, ListSelectionListener, DragSourceListener,
DragGestureListener, DropTargetListener, Transferable{
static final Logger log = LoggerFactory.getLogger(UITagTreePanel.class);
/** The scrollpane for the code tree.*/
private JScrollPane sp = null;
/** The label for the tree of codes.*/
public JLabel lblCodesList = null;
/** The button to cancel the parnt dialog.*/
private UIButton pbCancel = null;
/** The button to expand all folder in the tree.*/
private UIButton pbExpand = null;
/** The button the to open the relevant help.*/
public UIButton pbHelp = null;
/** The button to add a new tag.*/
private UIButton pbNewTag = null;
/** The button to add a new Group.*/
private UIButton pbNewGroup = null;
/** The button to move the working area from right to bottom left and back.*/
private UIButton pbMove = null;
/** The list of nodes for the current code.*/
private Vector oNodes = new Vector();
/** The working list of nodes to tag.*/
private UIWorkingList oWorkingList = null;
/** The scrollpane that the list is in.*/
private JScrollPane oWorkingScroll = null;
/** The label for the list.*/
private JLabel lblViews = null;
/** The labe for the nodes working area.*/
private JLabel lblNodes = null;
/** The button to deselect all nodes in the lists.*/
private UIButton pbDeselectAll = null;
/** The button to insert the selected nodes into the current view.*/
private UIButton pbInsert = null;
/** The main panel holding the list and tree.*/
private JPanel centerpanel = null;
/** The textfield to enter new code / group names.*/
private JTextField tfNewCode = null;
/** the JTree holding the code and code grouping information to assign codes from.*/
private JTree tree = null;
/** The tree model.*/
private DefaultTreeModel treemodel = null;
/** The top node of the tree contents.*/
private DefaultMutableTreeNode top = null;
/** The current Model.*/
private IModel model = null;
private UITagTreePanel me = null;
/** The DragSource object associated with this draggable item.*/
private DragSource dragSource;
private boolean isFilter = false;
private int hotspot = new JCheckBox().getPreferredSize().width;
/** The main split pain.*/
private JSplitPane oSplitter = null;
/** The data flavors supported by this class.*/
public static final DataFlavor[] supportedFlavors = { null };
static {
try { supportedFlavors[0] = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType+"; class=com.compendium.ui.tags.UITagTreePanel", null); } //$NON-NLS-1$
catch (Exception ex) { log.error("Error...", ex); }
}
private int nOrientation = JSplitPane.VERTICAL_SPLIT;
/** Holds a list of all the currently displayed tree renderers.*/
private Hashtable htAllRenderers = new Hashtable(51);
/** The row to have a yellow border*/
private int highlightRow = -2;
/**
* Constructor.
*/
public UITagTreePanel() {
super();
model = ProjectCompendium.APP.getModel();
showCodePanel();
me = this;
updateSelectionListView();
tfNewCode.requestFocus();
}
/**
* Draw the panel contents.
*/
private void showCodePanel() {
setLayout(new BorderLayout());
setFont(ProjectCompendium.APP.currentDefaultFont);
JPanel leftpanel = new JPanel(new BorderLayout());
// TOP PANEL
JPanel toppanel = createTopPanel();
leftpanel.add(toppanel, BorderLayout.NORTH);
String sOrientation = FormatProperties.getFormatProp("tagsViewOrientation"); //$NON-NLS-1$
if (sOrientation != null && sOrientation.equals("horizontal")) { //$NON-NLS-1$
nOrientation = JSplitPane.HORIZONTAL_SPLIT;
}
// MAIN PANEL
centerpanel = new JPanel(new BorderLayout());
sp = createTree();
sp.addMouseListener(oWorkingList);
tree.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent e) {
oWorkingList.mouseClicked(e);
}
});
centerpanel.add(sp, BorderLayout.CENTER);
JPanel buttonpanel = new JPanel();
pbExpand = new UIButton(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.expandallButton")); //$NON-NLS-1$
pbExpand.setMnemonic(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.expandallButtonMnemonic").charAt(0));
pbExpand.addActionListener(this);
pbExpand.setEnabled(true);
buttonpanel.add(pbExpand);
centerpanel.add(buttonpanel, BorderLayout.SOUTH);
leftpanel.add(centerpanel, BorderLayout.CENTER);
JPanel rightpanel = createUsagePanel();
oSplitter = new JSplitPane(nOrientation, true, leftpanel, rightpanel) {
boolean isPainted = false;
boolean hasProportionalLocation = false;
double proportionalLocation;
public void setDividerLocation(double proportionalLocation) {
if (!isPainted) {
hasProportionalLocation = true;
this.proportionalLocation = proportionalLocation;
} else {
super.setDividerLocation(proportionalLocation);
}
}
public void paint(Graphics g) {
if (!isPainted) {
if (hasProportionalLocation) {
super.setDividerLocation(proportionalLocation);
}
isPainted = true;
}
super.paint(g);
}
};
oSplitter.setOneTouchExpandable(true);
oSplitter.setDividerSize(8);
oSplitter.setContinuousLayout(true);
oSplitter.setMinimumSize(new Dimension(200, oSplitter.getPreferredSize().height));
oSplitter.setDividerLocation(0.5);
add(oSplitter, BorderLayout.CENTER);
add(createButtonPanel(), BorderLayout.SOUTH);
addFocusListener( new FocusListener() {
public void focusGained(FocusEvent e) {
tree.requestFocus();
}
public void focusLost(FocusEvent e) {
}
});
validate();
}
private JPanel createUsagePanel() {
JPanel panel = new JPanel(new BorderLayout());
// Add labels
JPanel labelpanel = new JPanel(new BorderLayout());
JPanel panel1 = new JPanel(new BorderLayout());
panel1.setBorder(new EmptyBorder(5,5,0,5));
lblViews = new JLabel(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.workingarea")); //$NON-NLS-1$
lblViews.setAlignmentX(JLabel.LEFT_ALIGNMENT);
panel1.add(lblViews, BorderLayout.CENTER);
JPanel panel2 = new JPanel(new BorderLayout());
panel2.setBorder(new EmptyBorder(5,5,5,5));
lblNodes = new JLabel(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.nodes")); //$NON-NLS-1$
lblNodes.setAlignmentX(JLabel.LEFT_ALIGNMENT);
panel2.add(lblNodes, BorderLayout.CENTER);
labelpanel.add(panel1, BorderLayout.NORTH);
labelpanel.add(panel2, BorderLayout.CENTER);
oWorkingList = new UIWorkingList();
oWorkingList.getList().getSelectionModel().addListSelectionListener(this);
oWorkingScroll = new JScrollPane(oWorkingList.getList());
oWorkingScroll.addMouseListener(oWorkingList);
//if (this.nOrientation == JSplitPane.HORIZONTAL_SPLIT) {
Dimension size = tree.getPreferredSize();
oWorkingScroll.setPreferredSize(new Dimension(250, size.height));
//} else {
// oWorkingScroll.setPreferredSize(new Dimension(250, 250));
//}
JPanel buttonpanel = new JPanel();
pbInsert = new UIButton(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.insertButton")); //$NON-NLS-1$
pbInsert.setMnemonic(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.insertButtonMnemonic").charAt(0));
pbInsert.addActionListener(this);
buttonpanel.add(pbInsert);
pbDeselectAll = new UIButton(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.deselectallButton")); //$NON-NLS-1$
pbDeselectAll.setMnemonic(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.deselectallButtonMnemonic").charAt(0));
pbDeselectAll.addActionListener(this);
buttonpanel.add(pbDeselectAll);
//buttonpanel.add(pbSelectAll);
buttonpanel.add(pbDeselectAll);
panel.add(labelpanel, BorderLayout.NORTH);
panel.add(oWorkingScroll, BorderLayout.CENTER);
panel.add(buttonpanel, BorderLayout.SOUTH);
return panel;
}
private JPanel createTopPanel() {
JPanel toppanel = new JPanel(new BorderLayout());
JPanel newpanel = new JPanel(new BorderLayout());
newpanel.setBorder(new EmptyBorder(5,5,0,5));
tfNewCode = new JTextField(""); //$NON-NLS-1$
tfNewCode.setColumns(20);
tfNewCode.setMargin(new Insets(2,2,2,2));
newpanel.add(tfNewCode, BorderLayout.CENTER);
tfNewCode.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
int modifiers = e.getModifiers();
if (keyCode == KeyEvent.VK_ENTER && modifiers == 0) {
onAddTags(tfNewCode.getText());
}
}
});
JPanel buttonpanel = new JPanel();
pbNewTag = new UIButton(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.maketagButton")){ public boolean hasFocus(){ return true; }}; //$NON-NLS-1$
pbNewTag.setToolTipText(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.maketagButtonTip")); //$NON-NLS-1$
pbNewTag.setMnemonic(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.maketagButtonMnemonic").charAt(0));
pbNewTag.addActionListener(this);
pbNewTag.setFocusPainted(true);
buttonpanel.add(pbNewTag);
pbNewGroup = new UIButton(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.makegroupButton")); //$NON-NLS-1$
pbNewGroup.setToolTipText(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.makegroupButtonTip")); //$NON-NLS-1$
pbNewGroup.setMnemonic(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.makegroupButtonMnemonic").charAt(0));
pbNewGroup.addActionListener(this);
buttonpanel.add(pbNewGroup);
toppanel.add(newpanel, BorderLayout.CENTER);
toppanel.add(buttonpanel, BorderLayout.SOUTH);
return toppanel;
}
/**
* Create and return the button panel.
*/
private JPanel createButtonPanel() {
JPanel oButtonPanel = new JPanel();
pbCancel = new UIButton(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.closeButton")); //$NON-NLS-1$
pbCancel.setMnemonic(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.closeButtonMnemonic").charAt(0));
pbCancel.addActionListener(this);
oButtonPanel.add(pbCancel);
String sOrientation = FormatProperties.getFormatProp("tagsViewOrientation"); //$NON-NLS-1$
if (sOrientation == null || (!sOrientation.equals("vertical") && !sOrientation.equals("horizontal"))) { //$NON-NLS-1$ //$NON-NLS-2$
sOrientation = "vertical"; //$NON-NLS-1$
}
if (nOrientation == JSplitPane.HORIZONTAL_SPLIT) {
pbMove = new UIButton(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.verticalsplitButton")); //$NON-NLS-1$
pbMove.setToolTipText(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.verticalsplitButtonTip")); //$NON-NLS-1$
pbMove.setMnemonic(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.verticalsplitButtonMnemonic").charAt(0));
pbMove.addActionListener(this);
} else {
pbMove = new UIButton(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.horizontalsplitButton")); //$NON-NLS-1$
pbMove.setToolTipText(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.horizontalsplitButtonTip")); //$NON-NLS-1$
pbMove.setMnemonic(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.horizontalsplitButtonMnemonic").charAt(0));
pbMove.addActionListener(this);
}
oButtonPanel.add(pbMove);
pbHelp = new UIButton(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.helpButton")); //$NON-NLS-1$
pbHelp.setMnemonic(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.helpButtonMnemonic").charAt(0));
ProjectCompendium.APP.mainHB.enableHelpOnButton(pbHelp, "tag.assignment", ProjectCompendium.APP.mainHS); //$NON-NLS-1$
oButtonPanel.add(pbHelp);
return oButtonPanel;
}
public void valueChanged(ListSelectionEvent e) {
checkTagsForSelectedNodes();
}
public void hideHint() {
if (oWorkingList != null) {
oWorkingList.hideHint();
}
}
/**
* Check the tags that correspond to the currently selected nodes in the working area.
*/
private void checkTagsForSelectedNodes() {
Hashtable selectedCodes = new Hashtable(51);
Hashtable universalCodes = new Hashtable(51);
JTable table = oWorkingList.getList();
int[] rows = table.getSelectedRows();
int row = 0;
NodeSummary node = null;
Enumeration codes = null;
Code code = null;
String sCodeID = ""; //$NON-NLS-1$
Integer num = null;
for (int i=0; i<rows.length; i++) {
row = rows[i];
node = oWorkingList.getNodeAt(row);
// If something has changed that drastically, abort.
if (node == null) {
return;
}
for (codes = node.getCodes(); codes.hasMoreElements(); ) {
code = (Code)codes.nextElement();
sCodeID = code.getId();
if (!selectedCodes.containsKey(sCodeID)) {
selectedCodes.put(sCodeID, code);
}
if (!universalCodes.containsKey(code.getId())) {
universalCodes.put(sCodeID, new Integer(1));
} else {
num = (Integer)universalCodes.get(sCodeID);
int inum = num.intValue();
inum = inum+1;
universalCodes.put(sCodeID, new Integer(inum));
}
}
}
DefaultMutableTreeNode treenode = null;
CheckNode check = null;
int inum = 0;
for (Enumeration e = top.preorderEnumeration(); e.hasMoreElements();) {
treenode = (DefaultMutableTreeNode)e.nextElement();
check = (CheckNode)treenode.getUserObject();
if (check.getData() instanceof Code) {
code = (Code)check.getData();
sCodeID = code.getId();
if (selectedCodes.containsKey(sCodeID)) {
if (universalCodes.containsKey(code.getId())) {
num = (Integer)universalCodes.get(sCodeID);
inum = num.intValue();
}
check.setChecked(true);
if (inum == rows.length) {
check.setUniversal(true);
} else {
check.setUniversal(false);
}
DefaultMutableTreeNode parent = (DefaultMutableTreeNode)treenode.getParent();
if (!tree.isExpanded(new TreePath(parent.getPath()))) {
tree.expandPath(new TreePath(parent.getPath()));
}
// tree.scrollPathToVisible(path);
} else {
check.setChecked(false);
check.setUniversal(false);
}
}
}
tree.validate();
tree.repaint();
}
/**
* Updates the list of nodes for the currently selected tags based on the selected group.
*/
private void updateFilterListGroupView() {
pbDeselectAll.setText(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.selectallButton")); //$NON-NLS-1$
pbDeselectAll.setMnemonic(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.selectallButtonMnemonic").charAt(0));
isFilter = true;
deselectInView();
removeAllNodes();
Hashtable htNodesCheck = new Hashtable();
Vector filterNodes = new Vector(51);
String userID = model.getUserProfile().getId();
try {
filterNodes = new Vector(51);
TreePath path = tree.getSelectionPath();
if (path != null) {
Code code = null;
Vector nodes = null;
NodeSummary node = null;
DefaultMutableTreeNode treenode = null;
int countj = 0;
String sNodeID = ""; //$NON-NLS-1$
treenode = (DefaultMutableTreeNode)path.getLastPathComponent();
if (treenode.getUserObject() instanceof CheckNode) {
CheckNode check = (CheckNode)treenode.getUserObject();
if (check.getData() instanceof Vector) {
Vector group = (Vector)check.getData();
Hashtable htCodeGroup = model.getCodeGroup((String)group.elementAt(0));
Hashtable children = (Hashtable)htCodeGroup.get("children"); //$NON-NLS-1$
int count = children.size();
for (Enumeration e=children.elements(); e.hasMoreElements();) {
code = (Code)e.nextElement();
nodes = model.getCodeService().getNodes(model.getSession(), code.getId(), userID);
countj = nodes.size();
for (int j=0; j< countj; j++) {
node = (NodeSummary)nodes.elementAt(j);
if (node != null) {
node.initialize(model.getSession(), model);
sNodeID = node.getId();
if (!htNodesCheck.containsKey(sNodeID)) {
htNodesCheck.put(sNodeID, node);
filterNodes.addElement(node);
}
}
}
}
}
}
}
}
catch(Exception ex) {
log.error("Error...", ex);
ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.errorusage")+":\n\n"+ex.getMessage()); //$NON-NLS-1$
}
if (filterNodes.size() == 0) {
oNodes = filterNodes;
updateViewCount();
oWorkingList.refreshTable(oNodes);
} else {
filterNodes = CoreUtilities.sortList(filterNodes);
oNodes = filterNodes;
updateViewCount();
oWorkingList.refreshTable(oNodes);
}
}
/**
* Updates the list of nodes for the currently selected tags.
*/
private void updateFilterListView() {
pbDeselectAll.setText(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.selectallButton")); //$NON-NLS-1$
pbDeselectAll.setMnemonic(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.selectallButtonMnemonic").charAt(0));
isFilter = true;
deselectInView();
removeAllNodes();
Hashtable htNodesCheck = new Hashtable();
Vector filterNodes = new Vector(51);
String userID = model.getUserProfile().getId();
try {
Vector allNodes = new Vector(51);
filterNodes = new Vector(51);
TreePath[] paths = tree.getSelectionPaths();
if (paths != null) {
Vector allVectors = new Vector(paths.length);
TreePath path = null;
Code code = null;
Vector nodes = null;
NodeSummary node = null;
DefaultMutableTreeNode treenode = null;
int countj = 0;
String sNodeID = ""; //$NON-NLS-1$
for (int i=0; i<paths.length; i++) {
path = paths[i];
treenode = (DefaultMutableTreeNode)path.getLastPathComponent();
if (treenode.getUserObject() instanceof CheckNode) {
CheckNode check = (CheckNode)treenode.getUserObject();
if (check.getData() instanceof Code) {
code = (Code)check.getData();
nodes = model.getCodeService().getNodes(model.getSession(), code.getId(), userID);
countj = nodes.size();
for (int j=0; j< countj; j++) {
node = (NodeSummary)nodes.elementAt(j);
if (node != null) {
node.initialize(model.getSession(), model);
sNodeID = node.getId();
if (i==0) {
htNodesCheck.put(sNodeID, new Integer(1));
} else if (htNodesCheck.containsKey(sNodeID)) {
Integer num = (Integer)htNodesCheck.get(sNodeID);
int iNum = num.intValue();
iNum = iNum+1;
htNodesCheck.put(sNodeID, new Integer(iNum));
}
if (!allNodes.contains(node)) {
allNodes.addElement(node);
}
}
}
}
}
}
if (allNodes.size() == 0) {
oNodes = filterNodes;
updateViewCount();
oWorkingList.refreshTable(oNodes);
return;
}
if (paths.length == 1) {
filterNodes = allNodes;
} else {
int count = allNodes.size();
for (int i=0; i<count; i++) {
node = (NodeSummary)allNodes.elementAt(i);
sNodeID = node.getId();
if (htNodesCheck.containsKey(sNodeID)) {
Integer num = (Integer)htNodesCheck.get(sNodeID);
int iNum = num.intValue();
if (iNum == paths.length) {
filterNodes.addElement(node);
}
}
}
}
filterNodes = CoreUtilities.sortList(filterNodes);
}
}
catch(Exception ex) {
log.error("Error...", ex);
ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.errorusage2")+":\n\n"+ex.getMessage()); //$NON-NLS-1$
}
oNodes = filterNodes;
updateViewCount();
oWorkingList.refreshTable(oNodes);
}
private void deselectInView() {
UIViewFrame frame = ProjectCompendium.APP.getCurrentFrame();
if (frame != null) {
if (frame instanceof UIMapViewFrame) {
UIMapViewFrame mapFrame = (UIMapViewFrame)frame;
UIViewPane pane = mapFrame.getViewPane();
if (pane != null) {
pane.setSelectedNode(null, ICoreConstants.DESELECTALL);
pane.setSelectedLink(null, ICoreConstants.DESELECTALL);
}
} else if (frame instanceof UIListViewFrame) {
UIListViewFrame listFrame = (UIListViewFrame)frame;
UIList list = listFrame.getUIList();
if (list != null) {
list.deselectAll();
}
}
}
}
/**
* Updates the list of nodes for the currently selected nodes in the current view.
*/
private void updateSelectionListView() {
isFilter = false;
removeAllNodes();
Vector allNodes = new Vector(51);
Hashtable htNodesCheck = new Hashtable();
UIViewFrame frame = ProjectCompendium.APP.getCurrentFrame();
if (frame != null) {
if (frame instanceof UIMapViewFrame) {
UIMapViewFrame mapFrame = (UIMapViewFrame)frame;
UIViewPane pane = mapFrame.getViewPane();
if (pane != null) {
Enumeration e = pane.getSelectedNodes();
UINode node = null;
String sNodeID = ""; //$NON-NLS-1$
for (Enumeration en=e; en.hasMoreElements();) {
node = (UINode)en.nextElement();
sNodeID = node.getNode().getId();
if (!sNodeID.equals(ProjectCompendium.APP.getTrashBinID())
&& !sNodeID.equals(ProjectCompendium.APP.getInBoxID())) {
allNodes.addElement(node.getNode());
}
}
}
} else if (frame instanceof UIListViewFrame) {
UIListViewFrame listFrame = (UIListViewFrame)frame;
UIList list = listFrame.getUIList();
if (list != null) {
Enumeration e = list.getSelectedNodes();
NodePosition nodePos = null;
for (Enumeration en=e; en.hasMoreElements();) {
nodePos = (NodePosition)en.nextElement();
allNodes.addElement(nodePos.getNode());
}
}
}
}
/*if (allNodes.size() == 0) {
return;
}*/
allNodes = CoreUtilities.sortList(allNodes);
oNodes = allNodes;
updateViewCount();
oWorkingList.refreshTable(oNodes);
}
/**
* Updates the number of occurences for the given node.
*/
public void updateViewCount() {
if (isFilter) {
lblNodes.setText(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.filterednodes") +": "+ String.valueOf(oNodes.size())); //$NON-NLS-1$
} else {
lblNodes.setText(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.selectednodes") +": "+ String.valueOf(oNodes.size())); //$NON-NLS-1$
}
}
/**
* This is a convenience method to delete all the views in the hashtables and vectors.
*/
public void removeAllNodes() {
((UITagsListTableModel)((TableSorter)oWorkingList.getList().getModel()).getModel()).removeAllElements();
oNodes.removeAllElements();
oWorkingList.getList().revalidate();
oWorkingList.getList().repaint();
oWorkingScroll.repaint();
}
/**
* Repaint the tree in reflection to a visual change liske setting the default group.
*/
public void refresh() {
tree.validate();
tree.repaint();
}
/**
* Update the codes and code groups displayed in the tree.
*/
public void updateTreeData() {
model = ProjectCompendium.APP.getModel();
Enumeration e = tree.getExpandedDescendants(new TreePath(tree.getModel().getRoot()));
top = getTreeData();
treemodel = new DefaultTreeModel(top);
//tree.setLargeModel(true);
tree.setRootVisible(false);
tree.setModel(treemodel);
tree.repaint();
sp.repaint();
TreePath path = null;
String sGroupID = ""; //$NON-NLS-1$
DefaultMutableTreeNode node = null;
CheckNode check = null;
for (Enumeration en = e; en.hasMoreElements();) {
path = (TreePath)en.nextElement();
node = (DefaultMutableTreeNode)path.getLastPathComponent();
check = (CheckNode)node.getUserObject();
if (check.getData() instanceof Vector) {
sGroupID = (String)((Vector)check.getData()).elementAt(0);
node = findCodeGroup(sGroupID);
if (node != null) {
tree.expandPath(new TreePath(node.getPath()));
}
}
}
}
/**
* find the node for the given code group id
* @param sID the id of the node to find.
* @param DefaultMutableTreeNode the tree node if found else null.
*/
public DefaultMutableTreeNode findCodeGroup(String sID) {
DefaultMutableTreeNode node = null;
for (Enumeration e = top.preorderEnumeration(); e.hasMoreElements();) {
node = (DefaultMutableTreeNode)e.nextElement();
CheckNode check = (CheckNode)node.getUserObject();
if (check.getData() instanceof Vector) {
Vector data = (Vector)check.getData();
String sGroupID = (String)data.elementAt(0);
if (sGroupID.equals(sID))
break;
}
}
return node;
}
/**
* Create the JTree of codes and code groupings.
*/
private JScrollPane createTree() {
top = getTreeData();
if (top != null) {
// CREATE TREE
tree = new JTree(top);
treemodel = new DefaultTreeModel(top);
tree.setRootVisible(false);
tree.setModel(treemodel);
tree.setFont(ProjectCompendium.APP.currentDefaultFont);
CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();
tree.setCellRenderer(renderer);
tree.setCellEditor(new CheckBoxNodeEditor(tree));
tree.setEditable(true);
//UIDraggableTreeCellRenderer renderer = new UIDraggableTreeCellRenderer();
tree.setCellRenderer(renderer);
tree.setShowsRootHandles(true);
tree.setToggleClickCount(4);
tree.getSelectionModel().setSelectionMode
(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
MouseListener[] mice = tree.getMouseListeners();
MouseListener mouse = null;
for( int i=0; i<mice.length; i++){
mouse = mice[i];
tree.removeMouseListener(mouse);
}
dragSource = new DragSource();
dragSource.createDefaultDragGestureRecognizer((JComponent)tree, DnDConstants.ACTION_COPY_OR_MOVE, this);
DropTarget dropTarget = new DropTarget((JComponent)tree, this);
// Enable tool tips.
ToolTipManager.sharedInstance().registerComponent(tree);
tree.expandRow(0);
/*tree.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent e) {
tree.setSelectionRow(0);
}
public void focusLost(FocusEvent e) {
tree.clearSelection();
}
});*/
MouseListener ml = new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
boolean isRightMouse = SwingUtilities.isRightMouseButton(e);
boolean isLeftMouse = SwingUtilities.isLeftMouseButton(e);
if (ProjectCompendium.isMac &&
(e.getButton() == 3 && e.isShiftDown())) {
isRightMouse = true;
isLeftMouse = false;
}
if (tree.isEditing()) {
tree.stopEditing();
}
/*if (!tree.hasFocus()) {
tree.requestFocus();
}*/
int nClicks = e.getClickCount();
TreePath path = tree.getPathForLocation(e.getX(), e.getY());
//int row = tree.getRowForLocation(e.getX(), e.getY());
if (path != null) {
DefaultMutableTreeNode thenode = (DefaultMutableTreeNode)path.getLastPathComponent();
CheckNode check = (CheckNode)thenode.getUserObject();
if (check.getData() instanceof Code) {
Code code = (Code)check.getData();
if (isRightMouse) {
if(nClicks == 1) {
tree.setSelectionPath(path);
DefaultMutableTreeNode parent = (DefaultMutableTreeNode)thenode.getParent();
String sCodeGroupID = ""; //$NON-NLS-1$
if (parent != null) {
CheckNode group = (CheckNode)parent.getUserObject();
if (group.isGroup()) {
sCodeGroupID = (String)((Vector)group.getData()).elementAt(0);
}
}
UITagTreeLeafPopupMenu pop = new UITagTreeLeafPopupMenu(me, code, sCodeGroupID);
pop.show(tree, e.getX(), e.getY());
}
} else if (isLeftMouse) {
if (nClicks == 1) {
if(e.getX() < tree.getPathBounds(path).x + hotspot) {
if (oWorkingList.getList().getSelectedRowCount() > 0) {
check.setChecked(!check.isChecked());
if (check.isChecked()) {
onAddCodeToNodes(code);
checkTagsForSelectedNodes();
} else {
onRemoveCodeFromNodes(code);
if (isFilter) {
updateFilterListView();
}
checkTagsForSelectedNodes();
}
tree.repaint();
} else {
ProjectCompendium.APP.displayMessage(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.selectnodes"), LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.tags")); //$NON-NLS-1$ //$NON-NLS-2$
}
} else {
boolean isSelected = tree.isPathSelected(path);
if (isSelected && !e.isShiftDown()) {
tree.startEditingAtPath(path);
} else {
if (!e.isShiftDown()) {
tree.clearSelection();
}
if (isSelected && e.isShiftDown()) {
tree.removeSelectionPath(path);
} else if (!isSelected) {
tree.addSelectionPath(path);
}
clearChecks();
tree.validate();
tree.repaint();
updateFilterListView();
}
}
}
}
} else {
if (isRightMouse) {
UITagTreeGroupPopupMenu pop = new UITagTreeGroupPopupMenu(me, (Vector)check.getData());
pop.show(tree, e.getX(), e.getY());
} else if (isLeftMouse) {
boolean isSelected = tree.isPathSelected(path);
if (isSelected) {
tree.startEditingAtPath(path);
} else {
tree.clearSelection();
tree.addSelectionPath(path);
updateFilterListGroupView();
checkTagsForSelectedNodes();
tree.repaint();
}
}
}
} else {
/*if (!isRightMouse) {
// have they clicked the folder expand/collpase icon?
int mouseX = e.getX();
path = tree.getClosestPathForLocation(mouseX, e.getY());
if(path != null){
int boxWidth;
Insets i = tree.getInsets();
BasicTreeUI ui = (BasicTreeUI)tree.getUI();
if(ui.getExpandedIcon() != null)
boxWidth = ui.getExpandedIcon().getIconWidth();
else
boxWidth = 8;
int depthOffset = 0;
if(tree.isRootVisible()) {
if(tree.getShowsRootHandles())
depthOffset = 1;
else
depthOffset = 0;
}
else if(!tree.getShowsRootHandles())
depthOffset = -1;
else
depthOffset = 0;
int nRowX = (ui.getLeftChildIndent()+ui.getRightChildIndent()) * ((path.getPathCount() - 1) + depthOffset);
int boxLeftX = nRowX - ui.getRightChildIndent() - boxWidth / 2;
boxLeftX += i.left;
int boxRightX = boxLeftX + boxWidth;
if (mouseX >= boxLeftX && mouseX <= boxRightX) {
if (tree.isExpanded(path)) {
tree.collapsePath(path);
} else {
tree.expandPath(path);
}
}
}
}*/
}
}
public void mousePressed(MouseEvent e) {
boolean isRightMouse = SwingUtilities.isRightMouseButton(e);
boolean isLeftMouse = SwingUtilities.isLeftMouseButton(e);
if (ProjectCompendium.isMac &&
(e.getButton() == 3 && e.isShiftDown())) {
isRightMouse = true;
isLeftMouse = false;
}
TreePath path = tree.getPathForLocation(e.getX(), e.getY());
if (!isRightMouse && path == null) {
// have they clicked the folder expand/collpase icon?
int mouseX = e.getX();
path = tree.getClosestPathForLocation(mouseX, e.getY());
if(path != null){
int boxWidth;
Insets i = tree.getInsets();
BasicTreeUI ui = (BasicTreeUI)tree.getUI();
if(ui.getExpandedIcon() != null)
boxWidth = ui.getExpandedIcon().getIconWidth();
else
boxWidth = 8;
int depthOffset = 0;
if(tree.isRootVisible()) {
if(tree.getShowsRootHandles())
depthOffset = 1;
else
depthOffset = 0;
}
else if(!tree.getShowsRootHandles())
depthOffset = -1;
else
depthOffset = 0;
int nRowX = (ui.getLeftChildIndent()+ui.getRightChildIndent()) * ((path.getPathCount() - 1) + depthOffset);
int boxLeftX = nRowX - ui.getRightChildIndent() - boxWidth / 2;
boxLeftX += i.left;
int boxRightX = boxLeftX + boxWidth;
if (mouseX >= boxLeftX && mouseX <= boxRightX) {
if (tree.isExpanded(path)) {
tree.collapsePath(path);
} else {
tree.expandPath(path);
}
}
}
}
}
};
tree.addMouseListener(ml);
tree.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
int modifiers = e.getModifiers();
if(keyCode == KeyEvent.VK_DELETE) {
TreePath path = tree.getSelectionPath();
if (path != null) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
CheckNode check = (CheckNode)node.getUserObject();
if(check.getData() instanceof Code) {
Code code = (Code)check.getData();
onDeleteCode(code);
}
}
e.consume();
}
else if (keyCode == KeyEvent.VK_ENTER ) {
TreePath path = tree.getSelectionPath();
if (path != null) {
int row = tree.getRowForPath(path);
boolean isSelected = tree.isPathSelected(path);
if (isSelected) {
tree.startEditingAtPath(path);
} else {
if (modifiers != KeyEvent.VK_CONTROL) {
tree.clearSelection();
}
if (tree.isRowSelected(row)) {
tree.removeSelectionRow(row);
} else {
tree.addSelectionRow(row);
}
tree.repaint();
}
}
} else if (keyCode == KeyEvent.VK_SPACE && modifiers == 0) {
TreePath path = tree.getSelectionPath();
if (path != null) {
clearChecks();
tree.validate();
tree.repaint();
updateFilterListView();
}
} else if (keyCode == KeyEvent.VK_SPACE && modifiers != KeyEvent.VK_SHIFT) {
TreePath path = null;
DefaultMutableTreeNode thenode = null;
CheckNode check = null;
Code code = null;
boolean updateFilterList = false;
TreePath[] paths = tree.getSelectionPaths();
if (oWorkingList.getList().getSelectedRowCount() > 0) {
int count = paths.length;
for (int i=0; i<count; i++) {
path = paths[i];
thenode = (DefaultMutableTreeNode)path.getLastPathComponent();
check = (CheckNode)thenode.getUserObject();
if (check.getData() instanceof Code) {
code = (Code)check.getData();
check.setChecked(!check.isChecked());
if (check.isChecked()) {
onAddCodeToNodes(code);
} else {
onRemoveCodeFromNodes(code);
updateFilterList = true;
}
tree.repaint();
}
}
checkTagsForSelectedNodes();
if (isFilter && updateFilterList) {
updateFilterListView();
}
} else {
ProjectCompendium.APP.displayMessage(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.selectnodes"), LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.tags")); //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
});
}
sp = new JScrollPane(tree);
Dimension size = tree.getPreferredSize();
sp.setPreferredSize(new Dimension(250, size.height));
return sp;
}
/**
* Clear the checked state for all CheckNode objects.
*/
public void clearChecks() {
DefaultMutableTreeNode node = null;
CheckNode check = null;
for (Enumeration e = top.preorderEnumeration(); e.hasMoreElements();) {
node = (DefaultMutableTreeNode)e.nextElement();
check = (CheckNode)node.getUserObject();
check.setChecked(false);
}
}
/**
* Process a button push event.
* @param evt the associated ActionEvent for the button push.
*/
public void actionPerformed(ActionEvent evt) {
Object source = evt.getSource();
if (source == pbExpand) {
JButton button = (JButton)source;
if (button.getText().equals(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.expandallButton"))) { //$NON-NLS-1$
expandAllTree();
button.setText(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.collapseallButton")); //$NON-NLS-1$
button.setMnemonic(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.collapseallButtonMnemonic").charAt(0));
}
else {
collapseAllTree();
button.setText(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.expandallButton")); //$NON-NLS-1$
button.setMnemonic(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.expandallButtonMnemonic").charAt(0));
}
} else if (source == pbMove) {
JButton button = (JButton)source;
if (button.getText().equals(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.verticalsplitButton"))) { //$NON-NLS-1$
oSplitter.setOrientation(JSplitPane.VERTICAL_SPLIT);
oSplitter.setDividerLocation(0.5);
FormatProperties.setFormatProp("tagsViewOrientation", "vertical"); //$NON-NLS-1$ //$NON-NLS-2$
FormatProperties.saveFormatProps();
ProjectCompendium.APP.oSplitter.resetToPreferredSizes();
button.setText(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.horizontalsplitButton")); //$NON-NLS-1$
button.setToolTipText(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.horizontalsplitButtonTip")); //$NON-NLS-1$
button.setMnemonic(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.horizontalsplitButtonMnemonic").charAt(0));
}
else {
oSplitter.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
oSplitter.setDividerLocation(0.5);
FormatProperties.setFormatProp("tagsViewOrientation", "horizontal"); //$NON-NLS-1$ //$NON-NLS-2$
FormatProperties.saveFormatProps();
button.setText(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.verticalsplitButton")); //$NON-NLS-1$
ProjectCompendium.APP.oSplitter.resetToPreferredSizes();
button.setToolTipText(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.verticalsplittipButtonTip")); //$NON-NLS-1$
button.setMnemonic(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.verticalsplitButtonMnemonic").charAt(0));
}
} else if (source == pbCancel) {
hideHint();
ProjectCompendium.APP.getMenuManager().removeTagsView(true);
} else if (source == pbNewTag) {
onAddTags(tfNewCode.getText());
} else if (source == pbNewGroup) {
onAddGroups(tfNewCode.getText());
} else if (source == pbDeselectAll) {
JButton button = (JButton)source;
if (button.getText().equals(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.deselectallButton"))) { //$NON-NLS-1$
oWorkingList.deselectAll();
clearChecks();
button.setText(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.selectallButton")); //$NON-NLS-1$
button.setMnemonic(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.selectallButtonMnemonic").charAt(0));
}
else {
oWorkingList.getList().selectAll();
button.setText(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.deselectallButton")); //$NON-NLS-1$
button.setMnemonic(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.deselectallButtonMnemonic").charAt(0));
}
} else if (source == pbInsert) {
try {
onInsert();
}
catch(Exception ex) {
log.error("Error...", ex);
log.info("Error: (UISearchResultDialog.actionPerformed) \n\n"+ex.getMessage()); //$NON-NLS-1$
}
}
}
/**
* Insert the selected nodes in the current view.
*/
private void onInsert() throws Exception {
int [] selection = oWorkingList.getList().getSelectedRows();
if (selection.length <=0) {
ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.pleaseselectnodes")); //$NON-NLS-1$
return;
}
UIViewFrame activeFrame = ProjectCompendium.APP.getCurrentFrame();
ProjectCompendium.APP.setWaitCursor();
activeFrame.setCursor(new Cursor(java.awt.Cursor.WAIT_CURSOR));
this.setCursor(new Cursor(java.awt.Cursor.WAIT_CURSOR));
int i=0;
String sNodeID = ""; //$NON-NLS-1$
NodeSummary node = null;
Vector addedNodes = new Vector(51);
if (activeFrame instanceof UIListViewFrame) {
// deselect nodes and links so pasted ones are only ones seleted - bz
((UIListViewFrame)activeFrame).getUIList().deselectAll();
int index = -1;
UIList list = list = ((UIListViewFrame)activeFrame).getUIList();
View listview = list.getView();
int nodeCount = listview.getNumberOfNodes();;
NodePosition[] nps = new NodePosition[selection.length];
NodePosition nodePos = null;
for(i=0;i<selection.length;i++) {
node = (NodeSummary)oWorkingList.getNodeAt(selection[i]);
if (node != null) {
sNodeID = node.getId();
nodePos = list.getNode(sNodeID);
if (nodePos == null) {
int xpos = 100;
int ypos = ( nodeCount + 1) * 10;
nodeCount++;
Date date = new Date();
NodePosition np = new NodePosition(listview, node, xpos, ypos, date, date);
nps[i]=np;
try {
nodePos = listview.addNodeToView(node, xpos, ypos);
}
catch (Exception e) {
log.error("Error...", e);
ProjectCompendium.APP.displayError("Error: (UITagTreePanel.onInsert1)\n\n" + e.getMessage()); //$NON-NLS-1$
System.out.flush();
}
}
else {
addedNodes.addElement(new Integer(list.getIndexOf(nodePos.getNode())));
}
}
}
int len = listview.getNumberOfNodes();
// FORCE SORTER UPDATE
((ListTableModel)((TableSorter)list.getList().getModel()).getModel()).refreshTable();
int count = addedNodes.size();
for (int j=0;j<count; j++) {
list.selectNode(((Integer)addedNodes.elementAt(j)).intValue(), ICoreConstants.MULTISELECT);
}
list.insertNodes(nps, len);
for (int k=0; k<nps.length; k++) {
list.selectNode(k+len, ICoreConstants.MULTISELECT);
}
}
else {
UIViewPane uiviewpane = ((UIMapViewFrame)activeFrame).getViewPane();
ViewPaneUI viewpaneui = uiviewpane.getUI();
for(i=0;i<selection.length;i++) {
node = (NodeSummary)oWorkingList.getNodeAt(selection[i]);
if (node != null) {
sNodeID = node.getId();
if (uiviewpane.get(sNodeID) == null) {
int hPos = activeFrame.getHorizontalScrollBarPosition();
int vPos = activeFrame.getVerticalScrollBarPosition();
int xpos = hPos + ViewPaneUI.LEFTOFFSET;
int ypos = vPos + ((i+1)*ViewPaneUI.INTERNODE_DISTANCE);
try {
UINode uinode = viewpaneui.addNodeToView(node,xpos,ypos);
addedNodes.addElement(uinode);
}
catch (Exception e) {
log.error("Error...", e);
ProjectCompendium.APP.displayError("Error: (UITagTreePanel.onInsert2)\n\n" + e.getMessage()); //$NON-NLS-1$
System.out.flush();
}
} else {
UINode uinode = (UINode)uiviewpane.get(sNodeID);
addedNodes.addElement(uinode);
}
}
}
int count = addedNodes.size();
UINode uinode = null;
for (int j=0;j<count; j++) {
uinode = (UINode)addedNodes.elementAt(j);
uinode.setRollover(false);
uinode.setSelected(true);
uiviewpane.setSelectedNode(uinode, ICoreConstants.MULTISELECT);
}
}
this.setCursor(Cursor.getDefaultCursor());
activeFrame.setCursor(Cursor.getDefaultCursor());
ProjectCompendium.APP.setDefaultCursor();
}
private void onAddTags(String tags) {
if (tags.equals("")) { //$NON-NLS-1$
ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.messageentertagname")); //$NON-NLS-1$
tfNewCode.requestFocus();
}
Vector vtNewCodes = new Vector();
int num = 0;
StringTokenizer st = new StringTokenizer(tags,","); //$NON-NLS-1$
while(st.hasMoreTokens()) {
String c = st.nextToken();
if (c.length() > 50) {
ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.warning50charsA")+"\n\n"+LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.warning50charsB")); //$NON-NLS-1$
tfNewCode.requestFocus();
return;
}
vtNewCodes.addElement(c.trim());
}
IModel model = ProjectCompendium.APP.getModel();
PCSession session = ProjectCompendium.APP.getModel().getSession();
String author = model.getUserProfile().getUserName();
Date creationDate = new Date();
Date modificationDate = creationDate;
String description = LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.nodesc"); //$NON-NLS-1$
String behavior = LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.nobehaviour"); //$NON-NLS-1$
int count = vtNewCodes.size();
for(int i=0;i<count;i++) {
try {
String name = (String)vtNewCodes.elementAt(i);
String sCodeID = model.getUniqueID();
if (ProjectCompendium.APP.getModel().codeNameExists(sCodeID, name)) {
ProjectCompendium.APP.displayMessage(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.warningtagexists")+name+"\n\n", LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.tagmaintenance")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
else {
//UPDATE DATABASE
Code code = model.getCodeService().createCode(session, sCodeID, author, creationDate,
modificationDate, name, description, behavior);
// UPDATE MODEL
model.addCode(code);
onAddCodeToNodes(code);
updateTreeData();
}
}
catch(SQLException ex) {
ProjectCompendium.APP.displayError("Exception: (UICodeMaintPanel.onAdd)\n\n)" + ex.getMessage()); //$NON-NLS-1$
}
}
checkTagsForSelectedNodes();
ProjectCompendium.APP.updateCodeChoiceBoxData();
tfNewCode.setText(""); //$NON-NLS-1$
}
private void onAddGroups(String groups) {
Vector vtNewCodes = new Vector();
int num = 0;
StringTokenizer st = new StringTokenizer(groups,","); //$NON-NLS-1$
while(st.hasMoreTokens()) {
String c = st.nextToken();
if (c.length() > 100) {
ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.warning100charsA")+"\n\n"+LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.warning100charsB")); //$NON-NLS-1$
tfNewCode.requestFocus();
return;
}
vtNewCodes.addElement(c.trim());
}
IModel model = ProjectCompendium.APP.getModel();
PCSession session = ProjectCompendium.APP.getModel().getSession();
String sAuthor = model.getUserProfile().getUserName();
Date date = new Date();
for(int i=0;i<vtNewCodes.size();i++) {
String name = (String)vtNewCodes.elementAt(i);
try {
String sCodeGroupID = model.getUniqueID();
//ADD NEW CODE TO DATABASE
(model.getCodeGroupService()).createCodeGroup(model.getSession(), sCodeGroupID, sAuthor, name, date, date);
// UPDATE MODEL
Vector group = new Vector(2);
group.addElement(sCodeGroupID);
group.addElement(name);
model.addCodeGroup(sCodeGroupID, group);
updateTreeData();
}
catch(SQLException ex) {
ProjectCompendium.APP.displayError("Error: (UICodeMaintPanel.onAdd)" + ex.getMessage()); //$NON-NLS-1$
}
}
tfNewCode.setText(""); //$NON-NLS-1$
}
/**
* Handle a request to delete the selected codes.
*/
public void onDeleteCode(Code code) {
IModel model = ProjectCompendium.APP.getModel();
PCSession session = model.getSession();
try {
// CHECK FOR ASSOCIATIONS
int count = model.getCodeService().getNodeCount(session, code.getId());
if (count > 0) {
ProjectCompendium.APP.displayMessage(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.warningassociatednodes"), LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.deletetag")); //$NON-NLS-1$ //$NON-NLS-2$
return;
}
else {
int response = JOptionPane.showConfirmDialog(ProjectCompendium.APP, LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.deletetagconfirmation")+": "+code.getName()+"?", //$NON-NLS-1$ //$NON-NLS-2$
LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.deletetag"), JOptionPane.YES_NO_OPTION); //$NON-NLS-1$
if (response == JOptionPane.NO_OPTION || response == JOptionPane.CLOSED_OPTION) {
return;
} else {
String sCodeID = code.getId();
// UPDATE DATABASE
model.getCodeService().delete(session, sCodeID);
// UPDATE MODEL
model.removeCode(code);
updateTreeData();
ProjectCompendium.APP.updateCodeChoiceBoxData();
}
}
}
catch(Exception ex) {
ProjectCompendium.APP.displayError("Error: (UICodeCodeMaintPanel.onDeleteCode)\n\n" + ex.getMessage()); //$NON-NLS-1$
}
}
/**
* Handle a request to delete the selected codes.
*/
public void onRemoveCodeFromGroup(Code code, String sCodeGroupID) {
IModel model = ProjectCompendium.APP.getModel();
PCSession session = model.getSession();
try {
// UPDATE DATABASE
model.getGroupCodeService().delete(session, code.getId(), sCodeGroupID );
// UPDATE MODEL
model.removeCodeGroupCode(sCodeGroupID, code.getId());
if (sCodeGroupID.equals(ProjectCompendium.APP.getActiveCodeGroup())) {
ProjectCompendium.APP.updateCodeChoiceBoxData();
}
updateTreeData();
}
catch(Exception ex) {
ProjectCompendium.APP.displayError("Error: (UICodeCodeMaintPanel.onRemoveCodeFromGroup)" + ex.getMessage()); //$NON-NLS-1$
}
}
/**
* Create tree of nodes for the tree on the code assinment panel.
*
* @return DefaultMutableTreeNode, the top tree node for the tree.
*/
public DefaultMutableTreeNode getTreeData() {
// TOP NEEDS TO MATCH THE STRUCTURE OF THE REST OF THE TREE DATA
Vector topdata = new Vector(2);
topdata.addElement(new String("")); //$NON-NLS-1$
topdata.addElement(new String(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.treetoplabel"))); //$NON-NLS-1$
DefaultMutableTreeNode activeGroupNode = null;
CheckNode check = new CheckNode(topdata);
DefaultMutableTreeNode top = new DefaultMutableTreeNode(check);
try {
Vector order = new Vector(51);
Hashtable groups = model.getCodeGroups();
DefaultMutableTreeNode group = null;
DefaultMutableTreeNode code = null;
check = null;
// ADD CODE GROUPS
for(Enumeration e = groups.elements();e.hasMoreElements();) {
Hashtable nextGroup = (Hashtable)e.nextElement();
if (nextGroup.containsKey("group")) { //$NON-NLS-1$
Vector groupdata = (Vector)nextGroup.get("group"); //$NON-NLS-1$
String sCodeGroupID = (String)groupdata.elementAt(0);
check = new CheckNode(groupdata);
group = new DefaultMutableTreeNode(check);
Hashtable children = null;
if (nextGroup.containsKey("children")) { //$NON-NLS-1$
children = (Hashtable)nextGroup.get("children"); //$NON-NLS-1$
// ADD ALL CHILD CODES FOR THIS GROUP
Vector childorder = new Vector(51);
for(Enumeration e2 = children.elements();e2.hasMoreElements();) {
Code nextcode = (Code)e2.nextElement();
check = new CheckNode(nextcode);
code = new DefaultMutableTreeNode(check);
childorder.addElement(code);
}
childorder = UIUtilities.sortList(childorder);
if (childorder != null) {
int count = childorder.size();
for (int i=0; i<count; i++) {
group.add((DefaultMutableTreeNode)childorder.elementAt(i));
}
}
}
// DON'T SHOW EMPTY GROUPS
//if (children != null && children.size() > 0) {
// MAKE SURE ACTIVE GROUPS IS AT THE TOP OF THE TREE LATER
//if (sCodeGroupID.equals(ProjectCompendium.APP.getActiveCodeGroup()))
// activeGroupNode = group;
//else
order.addElement(group);
//}
}
}
// ADD NODES TO ROOT NODE
int jcount = order.size();
if (jcount > 0)
order = UIUtilities.sortList(order);
// ADD THE ACTIVE GROUP AT THE TOP
if (activeGroupNode != null)
top.add(activeGroupNode);
// ADD ALL OTHER GROUPS
for (int j=0; j<jcount; j++)
top.add((DefaultMutableTreeNode)order.elementAt(j));
// ADD ALL CODES NOT IN GROUPS
Hashtable ungroupedCodes = model.getUngroupedCodes();
Vector sortedUngroupedCodes = new Vector(51);
for(Enumeration un = ungroupedCodes.elements();un.hasMoreElements();) {
sortedUngroupedCodes.addElement((Code)un.nextElement());
}
sortedUngroupedCodes = CoreUtilities.sortList(sortedUngroupedCodes);
int lcount = sortedUngroupedCodes.size();
for (int l=0; l<lcount; l++) {
check = new CheckNode((Code)sortedUngroupedCodes.elementAt(l));
top.add(new DefaultMutableTreeNode(check));
}
}
catch (Exception io) {
io.printStackTrace();
}
this.top = top;
return top;
}
/**
* Indicates when nodes and link are selected and deselected
* @param selected true for selected false for deselected.
*/
public void setNodeOrLinkSelected(boolean selected) {
setNodeSelected(selected);
}
/**
* Indicates when nodes on a view are selected and deselected.
* @param selected true for selected false for deselected.
*/
public void setNodeSelected(boolean selected) {
if (selected) {
tree.clearSelection();
updateSelectionListView();
oWorkingList.getList().selectAll();
pbDeselectAll.setText(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.deselectallButton")); //$NON-NLS-1$
pbDeselectAll.setMnemonic(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.deselectallButtonMnemonic").charAt(0));
} else {
if (!isFilter) {
tree.clearSelection();
updateSelectionListView();
clearChecks();
refresh();
}
}
}
/**
* Add the given code to the code list.
*
* @param vCodeList the list of codes to add the code to.
* @param newCodem the code to add, if not already there.
*/
public boolean addCodeToList (Vector vCodeList, Code newCode) {
boolean found = false;
for(Enumeration e = vCodeList.elements();e.hasMoreElements();) {
Code code = (Code)e.nextElement();
if (code.getName().equals(newCode.getName())) {
found = true;
break;
}
}
if(!found){
vCodeList.addElement(newCode);
}
return (!found);
}
/**
* Remove the given code from the code list.
*
* @param vCodeList, the list of codes to remove the code from.
* @param newCodem, the code to remove, if there.
*/
public void removeCodeFromList (Vector vCodeList, Code removedCode) {
if(!vCodeList.contains(removedCode)){
vCodeList.removeElement(removedCode);
}
}
/**
* Expand all tree folders.
*/
public void expandAllTree() {
for (Enumeration e = top.children(); e.hasMoreElements();) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)e.nextElement();
tree.expandPath(new TreePath( ((DefaultTreeModel)tree.getModel()).getPathToRoot(node) ));
}
tree.repaint();
sp.repaint();
}
/**
* Collapse all tree folders.
*/
public void collapseAllTree() {
for (Enumeration e = top.children(); e.hasMoreElements();) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)e.nextElement();
tree.collapsePath(new TreePath( ((DefaultTreeModel)tree.getModel()).getPathToRoot(node) ));
}
tree.repaint();
sp.repaint();
}
/**
* Return the font size to its default and then appliy the passed text zoom.
* (To the default specificed by the user in the Project Options)
*/
public void onReturnTextAndZoom(int zoom) {
Font font = ProjectCompendium.APP.currentDefaultFont;
Font newFont = new Font(font.getName(), font.getStyle(), font.getSize()+zoom);
tree.setFont(newFont);
FontMetrics metrics = tree.getFontMetrics(newFont);
tree.setRowHeight(metrics.getHeight());
this.oWorkingList.onReturnTextAndZoom(zoom);
}
/**
* Return the font size to its default
* (To the default specificed by the user in the Project Options)
*/
public void onReturnTextToActual() {
tree.setFont(ProjectCompendium.APP.currentDefaultFont);
FontMetrics metrics = tree.getFontMetrics(ProjectCompendiumFrame.currentDefaultFont);
tree.setRowHeight(metrics.getHeight());
this.oWorkingList.onReturnTextToActual();
}
/**
* Increase the currently dislayed font size by one point.
*/
public void onIncreaseTextSize() {
Font font = tree.getFont();
Font newFont = new Font(font.getName(), font.getStyle(), font.getSize()+1);
tree.setFont(newFont);
FontMetrics metrics = tree.getFontMetrics(newFont);
tree.setRowHeight(metrics.getHeight());
this.oWorkingList.onIncreaseTextSize();
}
/**
* Reduce the currently dislayed font size by one point.
*/
public void onReduceTextSize() {
Font font = tree.getFont();
Font newFont = new Font(font.getName(), font.getStyle(), font.getSize()-1);
tree.setFont(newFont);
FontMetrics metrics = tree.getFontMetrics(newFont);
tree.setRowHeight(metrics.getHeight());
this.oWorkingList.onReduceTextSize();
}
/**
* Add the given code to the currently selected nodes
* @param oCode the code to add
*/
public void onAddCodeToNodes(Code oCode) {
UIViewFrame frame = ProjectCompendium.APP.getCurrentFrame();
if (oWorkingList.getNumberOfSelectedNodes() > 0) {
int[] rows = oWorkingList.getList().getSelectedRows();
int row = 0;
NodeSummary node = null;
for (int i=0; i<rows.length; i++) {
row = rows[i];
node = oWorkingList.getNodeAt(row);
if (node != null ){
try {
if (node.addCode(oCode)) {
}
}
catch(Exception ex) {
log.error("Error...", ex);
ProjectCompendium.APP.displayError("Error: (UITagTreePanel.onAddCodeToNodes1)\n\n"+ex.getMessage()); //$NON-NLS-1$
}
}
}
}
// INCASE NEED TO UPDATE 'T' INDICATORS
ProjectCompendium.APP.refreshIconIndicators();
}
/**
* Remove the given code from all selected nodes.
* @param oCode the code to remove.
*/
public void onRemoveCodeFromNodes(Code oCode) {
UIViewFrame frame = ProjectCompendium.APP.getCurrentFrame();
if (oWorkingList.getNumberOfSelectedNodes() > 0) {
int[] rows = oWorkingList.getList().getSelectedRows();
int row = 0;
NodeSummary node = null;
for (int i=0; i<rows.length; i++) {
row = rows[i];
node = oWorkingList.getNodeAt(row);
if (node != null) {
try {
if (node.hasCode(oCode.getName())) {
if (node.removeCode(oCode)) {
}
}
}
catch (NoSuchElementException e) {
log.error("Error...", e);
}
catch(Exception ex) {
log.error("Error...", ex);
ProjectCompendium.APP.displayError("Error: (UITagTreePanel.onRemoveCodeFromNodes1)\n\n"+ex.getMessage()); //$NON-NLS-1$
}
}
}
}
// INCASE NEED TO UPDATE 'T' INDICATORS
ProjectCompendium.APP.refreshIconIndicators();
}
/**
* Can be used to clean up variables used ot help with garbage collection.
*/
public void cleanUp() {
sp = null;
lblCodesList = null;
pbCancel = null;
pbExpand = null;
centerpanel = null;
tree = null;
treemodel = null;
top = null;
}
// INNER CLASSES
/**
* Inner class to render a tree item.
* @author Michelle Bachler
*/
private class CheckBoxNodeRenderer extends JPanel implements TreeCellRenderer {
private CheckNode box = null;
private JCheckBox cbCheckBox = null;
private JLabel label = new JLabel();
private JTextField field = new JTextField();
private Border border = null;
private Icon leafIcon = null;
private Icon openIcon = null;
private Icon closedIcon = null;
private Color oHighlight = Color.yellow;
private Border oMainBorder = null;
protected BorderLayout layout = null;
Color selectionBorderColor, selectionForeground, selectionBackground,
textForeground, textBackground;
protected JCheckBox getCheckBox() {
return cbCheckBox;
}
protected JTextField getField() {
return field;
}
protected CheckNode getNode() {
return box;
}
protected Border getFieldBorder() {
return border;
}
protected void setDefaultColors() {
field.setForeground(textForeground);
field.setBackground(textBackground);
label.setForeground(selectionForeground);
label.setBackground(selectionBackground);
setBackground(textBackground);
}
public CheckBoxNodeRenderer() {
setFont(ProjectCompendium.APP.currentDefaultFont);
oMainBorder = getBorder();
layout = new BorderLayout();
layout.setHgap(5);
setLayout(layout);
add(field, BorderLayout.CENTER);
field.setEditable(false);
border = field.getBorder();
field.setBorder(null);
DefaultTreeCellRenderer rend = new DefaultTreeCellRenderer();
leafIcon = rend.getLeafIcon();
openIcon = rend.getOpenIcon();
closedIcon = rend.getClosedIcon();
selectionForeground = UIManager.getColor("List.selectionForeground"); //$NON-NLS-1$
selectionBackground = UIManager.getColor("List.selectionBackground"); //$NON-NLS-1$
textForeground = UIManager.getColor("List.textForeground"); //$NON-NLS-1$
textBackground = UIManager.getColor("List.textBackground"); //$NON-NLS-1$
}
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row,
boolean hasFocus) {
if (cbCheckBox != null) {
remove(cbCheckBox);
cbCheckBox = null;
}
remove(label);
setBorder(oMainBorder);
DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
Object userObject = node.getUserObject();
box = (CheckNode)userObject;
if (!box.isGroup()) {
Code code = (Code)box.getData();
cbCheckBox = new JCheckBox();
cbCheckBox.setSelected(box.isChecked());
cbCheckBox.setFont(tree.getFont());
if (box.isChecked()) {
if (box.isUniversal()) {
cbCheckBox.setBackground(Color.orange);
} else {
cbCheckBox.setBackground(IUIConstants.DEFAULT_COLOR);
}
} else {
cbCheckBox.setBackground(tree.getBackground());
}
add(cbCheckBox, BorderLayout.WEST);
String text = code.getName();
int count = 0;
try {
count = (model.getCodeService()).getNodeCount(model.getSession(), code.getId());
}
catch(Exception ex) {
log.error("Error...", ex);
}
// HACK: for window/Mac bug. Leave space at end else when number grows it disappears off right edge
// Something wrong as layout manager should adjust really
field.setText(text+" ("+count+") "); //$NON-NLS-1$ //$NON-NLS-2$
field.setFont(tree.getFont());
if (selected) {
field.setForeground(selectionForeground);
field.setBackground(selectionBackground);
} else {
field.setForeground(textForeground);
field.setBackground(textBackground);
}
setToolTipText(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.clickltip")); //$NON-NLS-1$
layout.setHgap(2);
layout.invalidateLayout(this);
layout.layoutContainer(this);
} else {
add(label, BorderLayout.WEST);
Icon icon = null;
if (box.isGroup()) {
if (expanded)
icon = openIcon;
else
icon = closedIcon;
}
label.setIcon(icon);
label.setForeground(textForeground);
label.setBackground(textBackground);
Vector group = (Vector)box.getData();
field.setText((String)group.elementAt(1));
field.setFont(tree.getFont());
if ( (ProjectCompendium.APP.getActiveCodeGroup()).equals((String)group.elementAt(0)) && !selected ) {
field.setForeground(IUIConstants.DEFAULT_COLOR);
field.setBackground(textBackground);
} else {
if (selected) {
field.setForeground(selectionForeground);
field.setBackground(selectionBackground);
} else {
field.setForeground(textForeground);
field.setBackground(textBackground);
}
}
setToolTipText(LanguageProperties.getString(LanguageProperties.TAGS_BUNDLE, "UITagTreePanel.clicktip2")); //$NON-NLS-1$
if (row == highlightRow) {
setBorder(new LineBorder(oHighlight, 2));
}
}
setBackground(textBackground);
htAllRenderers.put(new Integer(row), this);
return this;
}
}
private class CheckBoxNodeEditor extends AbstractCellEditor implements TreeCellEditor {
CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();
CheckNode check = null;
JTree tree;
public CheckBoxNodeEditor(JTree tree) {
this.tree = tree;
}
public Object getCellEditorValue() {
return check;
}
public boolean shouldSelectCell(EventObject anEvent) {
return false;
}
public boolean stopCellEditing() {
check.setText(renderer.getField().getText());
updateTreeData();
if (isFilter) {
updateFilterListView();
} else {
updateSelectionListView();
}
return true;
}
public boolean isCellEditable(EventObject event) {
return true;
}
public Component getTreeCellEditorComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row) {
Component editor = renderer.getTreeCellRendererComponent(tree, value,
selected, expanded, leaf, row, true);
if (renderer.getCheckBox() != null) {
renderer.getCheckBox().setEnabled(false);
}
check = renderer.getNode();
JTextField field = renderer.getField();
field.setText(check.getText());
field.setBorder(renderer.getFieldBorder());
field.setEditable(true);
int cols = field.getColumns();
if (cols < 30) {
field.setColumns(30);
}
final JTree ftree = tree;
final JTextField ffield = field;
field.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
int modifiers = e.getModifiers();
if (keyCode == KeyEvent.VK_ENTER && modifiers == 0) {
if (ftree.isEditing()) {
ftree.stopEditing();
}
}
}
public void keyTyped(KeyEvent e) {
char keyChar = e.getKeyChar();
char[] key = {keyChar};
String sKeyPressed = new String(key);
int modifiers = e.getModifiers();
//JViewport viewport = sp.getViewport();
//Rectangle nodeBounds = ffield.getBounds();
//Point parentPos = SwingUtilities.convertPoint(ftree, nodeBounds.x, nodeBounds.y, viewport);
//sp.scrollRectToVisible(new Rectangle(parentPos.x+nodeBounds.width-5, parentPos.y, 5, 5));
if (ProjectCompendium.isMac && modifiers == ProjectCompendium.APP.shortcutKey) {
return;
} else {
if (( Character.isLetterOrDigit(keyChar) || sKeyPressed.equals(" ") || //$NON-NLS-1$
IUIConstants.NAVKEYCHARS.indexOf(sKeyPressed) != -1) ) {
String sText = ffield.getText();
if (check.isGroup() && sText.length()== 100) {
ffield.setText(sText.substring(0,100));
e.consume();
} else if (!check.isGroup() && sText.length() == 50) {
ffield.setText(sText.substring(0,50));
e.consume();
}
}
}
}
});
field.addFocusListener(new FocusListener(){
public void focusGained(FocusEvent e){}
public void focusLost(FocusEvent e){
ftree.stopEditing();
}
});
field.setFont(tree.getFont());
renderer.setDefaultColors();
return editor;
}
}
// DRAG AND DROP METHODS
// TRANSFERABLE
/**
* Returns an array of DataFlavor objects indicating the flavors the data
* can be provided in.
* @return an array of data flavors in which this data can be transferred
*/
public DataFlavor[] getTransferDataFlavors() {
return supportedFlavors;
}
/**
* Returns whether or not the specified data flavor is supported for
* this object.
* @param flavor the requested flavor for the data
* @return boolean indicating whether or not the data flavor is supported
*/
public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavor.isMimeTypeEqual(DataFlavor.javaJVMLocalObjectMimeType+"; class=com.compendium.ui.tags.UITagTreePanel"); //$NON-NLS-1$
}
/**
* Returns an object which represents the data to be transferred. The class
* of the object returned is defined by the representation class of the flavor.
*
* @param flavor the requested flavor for the data
* @see DataFlavor#getRepresentationClass
* @exception IOException if the data is no longer available in the requested flavor.
* @exception UnsupportedFlavorException if the requested data flavor is not supported.
*/
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
if (flavor.isMimeTypeEqual(DataFlavor.javaJVMLocalObjectMimeType+"; class=com.compendium.ui.tags.UITagTreePanel")) //$NON-NLS-1$
return this;
else return null;
}
private TreePath[] sourcepaths = null;
// SOURCE
/**
* A <code>DragGestureRecognizer</code> has detected
* a platform-dependent drag initiating gesture and
* is notifying this listener
* in order for it to initiate the action for the user.
* <P>
* @param e the <code>DragGestureEvent</code> describing
* the gesture that has just occurred
*/
public void dragGestureRecognized(DragGestureEvent e) {
InputEvent in = e.getTriggerEvent();
sourcepaths = null;
int action = e.getDragAction();
if (in instanceof MouseEvent) {
sourcepaths = tree.getSelectionPaths();
if (action == DnDConstants.ACTION_COPY) {
e.startDrag(DragSource.DefaultCopyDrop, this, this);
} else {
e.startDrag(DragSource.DefaultMoveDrop, this, this);
}
}
}
/**
* This method is invoked to signify that the Drag and Drop
* operation is complete. The getDropSuccess() method of
* the <code>DragSourceDropEvent</code> can be used to
* determine the termination state. The getDropAction() method
* returns the operation that the drop site selected
* to apply to the Drop operation. Once this method is complete, the
* current <code>DragSourceContext</code> and
* associated resources become invalid.
* HERE THE METHOD DOES NOTHING.
*
* @param e the <code>DragSourceDropEvent</code>
*/
public void dragDropEnd(DragSourceDropEvent e) {}
/**
* Called as the cursor's hotspot enters a platform-dependent drop site.
* This method is invoked when all the following conditions are true:
* <UL>
* <LI>The cursor's hotspot enters the operable part of a platform-
* dependent drop site.
* <LI>The drop site is active.
* <LI>The drop site accepts the drag.
* </UL>
* HERE THE METHOD DOES NOTHING.
*
* @param e the <code>DragSourceDragEvent</code>
*/
public void dragEnter(DragSourceDragEvent e) {}
/**
* Called as the cursor's hotspot exits a platform-dependent drop site.
* This method is invoked when any of the following conditions are true:
* <UL>
* <LI>The cursor's hotspot no longer intersects the operable part
* of the drop site associated with the previous dragEnter() invocation.
* </UL>
* OR
* <UL>
* <LI>The drop site associated with the previous dragEnter() invocation
* is no longer active.
* </UL>
* OR
* <UL>
* <LI> The current drop site has rejected the drag.
* </UL>
* HERE THE METHOD DOES NOTHING.
*
* @param e the <code>DragSourceEvent</code>
*/
public void dragExit(DragSourceEvent e) {}
/**
* Called as the cursor's hotspot moves over a platform-dependent drop site.
* This method is invoked when all the following conditions are true:
* <UL>
* <LI>The cursor's hotspot has moved, but still intersects the
* operable part of the drop site associated with the previous
* dragEnter() invocation.
* <LI>The drop site is still active.
* <LI>The drop site accepts the drag.
* </UL>
*
* @param e the <code>DragSourceDragEvent</code>
*/
public void dragOver(DragSourceDragEvent e) {
int action = e.getUserAction();
DragSourceContext context = e.getDragSourceContext();
Point loc = e.getLocation();
SwingUtilities.convertPointFromScreen(loc, tree);
tree.scrollRectToVisible(new Rectangle(loc.x-20, loc.y-20, 40, 40));
TreePath path = tree.getPathForLocation(loc.x, loc.y);
int row = tree.getRowForPath(path);
if (ProjectCompendium.isMac) {
if (action == DnDConstants.ACTION_COPY) {
context.setCursor(DragSource.DefaultCopyDrop);
} else if (action == DnDConstants.ACTION_MOVE) {
context.setCursor(DragSource.DefaultMoveDrop);
}
} else {
if (path != null) {
DefaultMutableTreeNode thenode = (DefaultMutableTreeNode)path.getLastPathComponent();
CheckNode check = (CheckNode)thenode.getUserObject();
if (check.isGroup()) {
if (action == DnDConstants.ACTION_COPY) {
context.setCursor(DragSource.DefaultCopyDrop);
} else if (action == DnDConstants.ACTION_MOVE) {
context.setCursor(DragSource.DefaultMoveDrop);
}
if (highlightRow != row) {
highlightRow = row;
Thread thread = new Thread() {
public void run() {
tree.repaint();
}
};
thread.start();
}
} else {
if (highlightRow != -2) {
highlightRow = -2;
Thread thread = new Thread() {
public void run() {
tree.repaint();
}
};
thread.start();
}
if (action == DnDConstants.ACTION_COPY) {
context.setCursor(DragSource.DefaultCopyNoDrop);
} else if (action == DnDConstants.ACTION_MOVE) {
context.setCursor(DragSource.DefaultMoveNoDrop);
}
}
} else {
if (highlightRow != -2) {
highlightRow = -2;
Thread thread = new Thread() {
public void run() {
tree.repaint();
}
};
thread.start();
}
if (action == DnDConstants.ACTION_COPY) {
context.setCursor(DragSource.DefaultCopyNoDrop);
} else if (action == DnDConstants.ACTION_MOVE) {
context.setCursor(DragSource.DefaultMoveNoDrop);
}
}
}
}
/**
* Called when the user has modified the drop gesture.
* This method is invoked when the state of the input
* device(s) that the user is interacting with changes.
* Such devices are typically the mouse buttons or keyboard
* modifiers that the user is interacting with.
*
* @param e the <code>DragSourceDragEvent</code>
*/
public void dropActionChanged(DragSourceDragEvent e) {}
//TARGET
/**
* Called if the user has modified
* the current drop gesture.
* <P>HERE DOES NOTHING</P>
* @param e the <code>DropTargetDragEvent</code>
*/
public void dropActionChanged(DropTargetDragEvent e) {}
/**
* Called when a drag operation is ongoing, while the mouse pointer is still
* over the operable part of the drop site for the <code>DropTarget</code>
* registered with this listener.
* <P>HERE DOES NOTHING</P>
* @param e the <code>DropTargetDragEvent</code>
*/
public void dragOver(DropTargetDragEvent e) {
}
/**
* Called while a drag operation is ongoing, when the mouse pointer has
* exited the operable part of the drop site for the
* <code>DropTarget</code> registered with this listener.
* <P>HERE DOES NOTHING</P>
* @param e the <code>DropTargetEvent</code>
*/
public void dragExit(DropTargetEvent e) {}
/**
* Called while a drag operation is ongoing, when the mouse pointer enters
* the operable part of the drop site for the <code>DropTarget</code>
* registered with this listener.
* <P>HERE DOES NOTHING</P>
* @param e the <code>DropTargetDragEvent</code>
*/
public void dragEnter(DropTargetDragEvent e) {}
/**
* Called when the drag operation has terminated with a drop on
* the operable part of the drop site for the <code>DropTarget</code>
* registered with this listener.
* @param e the <code>DropTargetDropEvent</code>
*/
public void drop(DropTargetDropEvent e) {
DropTarget drop = (DropTarget)e.getSource();
DropTargetContext context = e.getDropTargetContext();
context.getComponent().setCursor(new Cursor(java.awt.Cursor.DEFAULT_CURSOR));
try {
Transferable transferable = e.getTransferable();
if (!transferable.isDataFlavorSupported(new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType+"; class=com.compendium.ui.tags.UITagTreePanel", null))) { //$NON-NLS-1$
e.rejectDrop();
return;
}
} catch(Exception ec) {
ec.printStackTrace();
}
Point droploc = e.getLocation();
if (drop.getComponent() instanceof JTree) {
JTree tree = (JTree)drop.getComponent();
TreePath targetpath = tree.getPathForLocation(droploc.x, droploc.y);
if (sourcepaths != null && targetpath != null) {
DefaultMutableTreeNode targetnode = (DefaultMutableTreeNode)targetpath.getLastPathComponent();
CheckNode check = (CheckNode)targetnode.getUserObject();
if (check.getData() instanceof Code) {
e.rejectDrop();
return;
} else {
e.acceptDrop(e.getDropAction());
DefaultMutableTreeNode parent = null;
CheckNode group = null;
Vector codegroup = null;
String sCodeGroupID = ""; //$NON-NLS-1$
Code code = null;
String sAuthor = ""; //$NON-NLS-1$
Hashtable htCodeGroup = null;
Date date = new Date();
DefaultMutableTreeNode sourcenode = null;
CheckNode sourcecheck = null;
for (int i=0; i<sourcepaths.length; i++ ) {
sourcenode = (DefaultMutableTreeNode)sourcepaths[i].getLastPathComponent();
sourcecheck = (CheckNode)sourcenode.getUserObject();
if (sourcecheck.getData() instanceof Code) {
try {
codegroup = (Vector)check.getData();
sCodeGroupID = (String)codegroup.elementAt(0);
code = (Code)sourcecheck.getData();
sAuthor = model.getUserProfile().getUserName();
htCodeGroup = model.getCodeGroup(sCodeGroupID);
if (htCodeGroup.containsKey("children")) { //$NON-NLS-1$
Hashtable children = (Hashtable)htCodeGroup.get("children"); //$NON-NLS-1$
if (!children.containsKey(code.getId())) {
model.getGroupCodeService().createGroupCode(model.getSession(), code.getId(), sCodeGroupID, sAuthor, date, date);
model.addCodeGroupCode(sCodeGroupID, code.getId(), code);
if (e.getDropAction() == DnDConstants.ACTION_MOVE) {
parent = (DefaultMutableTreeNode)sourcenode.getParent();
String sParentCodeGroupID = ""; //$NON-NLS-1$
if (parent != null) {
group = (CheckNode)parent.getUserObject();
if (group.isGroup()) {
sParentCodeGroupID = (String)((Vector)group.getData()).elementAt(0);
model.getGroupCodeService().delete(model.getSession(), code.getId(), sParentCodeGroupID);
model.removeCodeGroupCode(sParentCodeGroupID, code.getId());
}
}
}
// YOU YOU ARE ADDING OR REMOVING FROM THE ACTIVEGROUP,
// REFRESH THE CHOICE BOX ON THE MAIN TOOLBAR
if (sCodeGroupID.equals(ProjectCompendium.APP.getActiveCodeGroup())) {
ProjectCompendium.APP.updateCodeChoiceBoxData();
}
this.updateTreeData();
DefaultMutableTreeNode node = findCodeGroup(sCodeGroupID);
if (node != null) {
tree.expandPath(new TreePath(node.getPath()));
}
} else {
log.warn("That tag is already in that group");
}
}
} catch (SQLException se) {
ProjectCompendium.APP.displayError("Error (UITagTreePanel.drop)\n\n"+se.getMessage()); //$NON-NLS-1$
}
}
}
}
}
}
e.dropComplete(true);
}
}