
package jp.riken.brain.ni.samuraigraph.base;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JCheckBox;

/**
 * A CheckBox class which has the "indeterminate" property.
 * If the check box is in the "indeterminate" state, this check box
 * is neither selected nor unselected.
 * Note that the method isSelected, which is inherited from the super class JCheckBox,
 * returns false in the indeterminate state.
 * 
 */
public class SGCheckBox extends JCheckBox implements ActionListener
{

	/**
	 * A flag for the indeterminate state.
	 */
	private boolean mIndeterminateFlag = false;


	/**
	 * The default constructor.
	 */
	public SGCheckBox()
	{
		super();
		this.init();
	}


	private void init()
	{
		// add itself as an action listener
		this.addActionListener( this );
	}


	/**
	 * Set the selected state.
	 * @param b - if b equals to Boolean.TRUE, this check box is set to be selected.
	 * and if b equals to Boolean.FALSE, to be not selected. If b equals to null,
	 * this check box is set to be in indeterminate state.
	 */
	public void setSelected( final Boolean b )
	{
		this.setIndeterminate(b==null);

		if( b!=null )
		{
			this.setSelected( b.booleanValue() );
		}
		else
		{
			this.setSelected(false);
		}
	}
	
	
	/**
	 * Returns the selected state.
	 * @return if this check box is not in the indeterminate state, it equals to
	 * Boolean.TRUE or Boolean.FALSE. Otherwise, it equals to null.
	 */
	public Boolean getSelected()
	{
		if( !this.mIndeterminateFlag )
		{
			return Boolean.valueOf( this.isSelected() );
		}
		else
		{
			return null;
		}
	}


	/**
	 * @param b
	 */
	private void setIndeterminate( final boolean b )
	{
		this.mIndeterminateFlag = b;

		Color cl;
		if( !b )
		{
			cl = Color.BLACK;
		}
		else
		{
			cl = Color.GRAY;
		}

		this.setForeground(cl);
	}



	/**
	 * 
	 */
	public void actionPerformed( ActionEvent e )
	{
		Object source = e.getSource();
		if( source.equals(this) )
		{
			// if the box is checked, set the value is determinated
			this.setIndeterminate(false);
		}
	}


}


