/*
 * #%L
 * ImageJ software for multidimensional image processing and analysis.
 * %%
 * Copyright (C) 2009 - 2012 Board of Regents of the University of
 * Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
 * Institute of Molecular Cell Biology and Genetics.
 * %%
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 
 * 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 HOLDERS 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.
 * 
 * The views and conclusions contained in the software and documentation are
 * those of the authors and should not be interpreted as representing official
 * policies, either expressed or implied, of any organization.
 * #L%
 */

package imagej.util.swing.tree;

import java.awt.Component;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.util.EventObject;

import javax.swing.AbstractCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreePath;

/**
 * A {@link TreeCellEditor} for check box tree nodes.
 * <p>
 * Thanks to John Zukowski for the <a
 * href="http://www.java2s.com/Code/Java/Swing-JFC/CheckBoxNodeTreeSample.htm"
 * >sample code</a> upon which this is based.
 * </p>
 * 
 * @author Curtis Rueden
 */
public class CheckBoxNodeEditor extends AbstractCellEditor implements
	TreeCellEditor
{

	private final CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();

	private final JTree tree;

	public CheckBoxNodeEditor(final JTree tree) {
		this.tree = tree;
	}

	@Override
	public Object getCellEditorValue() {
		final CheckBoxNodePanel panel = renderer.getLeafRenderer();
		final CheckBoxNodeData checkBoxNode =
			new CheckBoxNodeData(panel.label.getText(), panel.check.isSelected());
		return checkBoxNode;
	}

	@Override
	public boolean isCellEditable(final EventObject event) {
		boolean returnValue = false;
		if (event instanceof MouseEvent) {
			final MouseEvent mouseEvent = (MouseEvent) event;
			final TreePath path =
				tree.getPathForLocation(mouseEvent.getX(), mouseEvent.getY());
			if (path != null) {
				final Object node = path.getLastPathComponent();
				if ((node != null) && (node instanceof DefaultMutableTreeNode)) {
					final DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node;
					final Object userObject = treeNode.getUserObject();
					returnValue =
						((treeNode.isLeaf()) && (userObject instanceof CheckBoxNodeData));
				}
			}
		}
		return returnValue;
	}

	@Override
	public Component getTreeCellEditorComponent(final JTree tree,
		final Object value, final boolean selected, final boolean expanded,
		final boolean leaf, final int row)
	{

		final Component editor =
			renderer.getTreeCellRendererComponent(tree, value, true, expanded, leaf,
				row, true);

		// editor always selected / focused
		final ItemListener itemListener = new ItemListener() {

			@Override
			public void itemStateChanged(final ItemEvent itemEvent) {
				if (stopCellEditing()) {
					fireEditingStopped();
				}
			}
		};
		if (editor instanceof JCheckBox) {
			((JCheckBox) editor).addItemListener(itemListener);
		}

		return editor;
	}
}

@@ -2687,21 +2687,24 @@
  JTree t
+heT
 ree;%0A
-
 %0A%09public
@@ -2751,12 +2751,10 @@
 %09%09th
-is.t
+eT
 ree 
@@ -3090,44 +3090,15 @@
 ) %7B%0A
-%09%09boolean returnValue = false;%0A
 %09%09if 
+(!
 (eve
@@ -3122,20 +3122,32 @@
 seEvent)
- %7B%0A%09
+) return false;%0A
 %09%09final 
@@ -3190,17 +3190,17 @@
  event;%0A
-%09
+%0A
 %09%09final 
@@ -3218,18 +3218,20 @@
 th =%0A%09%09%09
-%09
 t
+heT
 ree.getP
@@ -3286,17 +3286,16 @@
 Y());%0A%09%09
-%09
 if (path
@@ -3295,25 +3295,25 @@
 f (path 
-!
+=
 = null) 
 %7B%0A%09%09%09%09fi
@@ -3304,20 +3304,31 @@
 = null) 
-%7B%0A%09%09
+return false;%0A%0A
 %09%09final 
@@ -3374,34 +3374,15 @@
 ();%0A
-%09%09
 %09%09if (
-(node != null) && 
+!
 (nod
@@ -3419,21 +3419,30 @@
 eNode)) 
-%7B%0A%09%09%09
+return false;%0A
 %09%09final 
@@ -3506,21 +3506,19 @@
 ) node;%0A
-%09%09
+%0A
 %09%09
-%09
 final Ob
@@ -3565,19 +3565,16 @@
 ();%0A
-%09%09%09
 %09%09return
 Valu
@@ -3573,23 +3573,9 @@
 turn
-Value =%0A%09%09%09%09%09%09(
+ 
 (tre
@@ -3592,14 +3592,12 @@
 af()
-)
  && 
-(
 user
@@ -3635,46 +3635,8 @@
 ata)
-);%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D%0A%09%09return returnValue
 ;%0A%09%7D
@@ -4224,17 +4224,43 @@
 x) %7B%0A%09%09%09
-(
+final JCheckBox checkBox = 
 (JCheckB
@@ -4269,17 +4269,29 @@
 ) editor
-)
+;%0A%09%09%09checkBox
 .addItem

Check box tree: tweak style