package de.roboshock.gui.util;

import java.awt.Color;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.AbstractCellEditor;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;

/**
* F�r Boolean-Werte in eine JTable. Im Gegensatz zu dem default 
* Checkbox Cell Editor wird die Checkbox dieses Editors nur dann
* getoggelt, wenn wirklich auf die Checkbox selbst geklickt wird. 
* Es reicht nicht mehr, irgendwo in die Tabellenzelle zu klicken.
* 
* @author xlex025
* @since 14.03.2008
*/
public class TsButtonCellEditor extends AbstractCellEditor
		implements TableCellEditor, MouseListener {
	private static final long	serialVersionUID	= -9042887773401777501L;

	// This is the component that will handle the editing of the cell value
	private JButton			button			= new JButton();
	private JPanel				area				= new JPanel();
	private boolean				oldValue;

	public TsButtonCellEditor() {
		area.setLayout(new GridBagLayout());
		GridBagConstraints cons = new GridBagConstraints();
		cons.fill = GridBagConstraints.NONE;
		cons.ipadx = 0;
		cons.ipady = 0;
		cons.gridx = 1;
		cons.gridy = 0;
		cons.anchor = GridBagConstraints.NORTH;
		cons.insets = new Insets(0, 0, 0, 0);
		//button.setBorder(null); // wichtig, sonst h�ngt sie zu tief!
		area.add(button, cons);

		JLabel spacerL = new JLabel();
		spacerL.setBackground(Color.BLUE);
		cons.fill = GridBagConstraints.HORIZONTAL;
		cons.gridx = 0;
		area.add(spacerL, cons);

		JLabel spacerR = new JLabel();
		spacerR.setBackground(Color.BLUE);
		cons.gridx = 2;
		area.add(spacerR, cons);

		button.addMouseListener(this);
	}

	// This method is called when a cell value is edited by the user.
	public Component getTableCellEditorComponent(JTable table, Object value,
			boolean isSelected, int rowIndex, int vColIndex) {

		oldValue = ((Boolean) value).booleanValue();
		button.setSelected(oldValue);
		return area;
	}

	// This method is called when editing is completed.
	// It must return the new value to be stored in the cell.
	public Object getCellEditorValue() {
		return new Boolean(button.isSelected());
	}

	public void mouseClicked(MouseEvent e) {
	}

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
	}

	public void mousePressed(MouseEvent e) {
	}

	public void mouseReleased(MouseEvent e) {
		// Damit andere Zellen ggf. sofort angepasst werden,
		// und nicht erst beim Verlassen des Editors durch click woanders hin.
		stopCellEditing();
	}

	public boolean stopCellEditing() {
		if (button.isSelected() == oldValue) {
			this.fireEditingCanceled();
		} else {
			this.fireEditingStopped();
		}
		return true;
	}

	// Niemanden informieren, damit die Tabelle kein 
	// PropertyChange-Event schmeisst !!!
	// (Hintergrund: Das Verlassen eine Checkbox bedeutet immer 
	// eine �nderung ihres Wertes, ABER das Verlassen des Editors 
	// darf nicht gleichgesetzt werden mit dem Verlassen der Checkbox,
	// weil der Editor auch aus den beiden Spacern links und rechts
	// neben der Checkbox besteht, und evtl. wurden ja nur
	// diese Spacer betreten und verlassen.)
	protected void fireEditingCanceled() {
	}

}
