//==============================================================================
//	
//	Copyright (c) 2002-
//	Authors:
//	* Andrew Hinton <ug60axh@cs.bham.ac.uk> (University of Birmingham)
//	* Dave Parker <david.parker@comlab.ox.ac.uk> (University of Oxford, formerly University of Birmingham)
//	
//------------------------------------------------------------------------------
//	
//	This file is part of PRISM.
//	
//	PRISM is free software; you can redistribute it and/or modify
//	it under the terms of the GNU General Public License as published by
//	the Free Software Foundation; either version 2 of the License, or
//	(at your option) any later version.
//	
//	PRISM 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 General Public License for more details.
//	
//	You should have received a copy of the GNU General Public License
//	along with PRISM; if not, write to the Free Software Foundation,
//	Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//	
//==============================================================================

package userinterface.util;

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.table.*;
import javax.swing.border.*;
import javax.swing.text.*;

@SuppressWarnings("serial")
public class PropertyTable extends JPanel implements ListSelectionListener, TableModelListener, ItemListener
{
	private PropertyTableModel theModel;

	private int lineWidth;

	/** Creates new form PropertyTable */
	public PropertyTable(PropertyTableModel theModel)
	{
		super();

		this.theModel = theModel;
		initComponents();

		theModel.setJTable(theTable);
		theModel.addTableModelListener(this);
		lineWidth = theTable.getRowHeight();
		theTable.setModel(theModel);
		theTable.setRowSelectionAllowed(true);
		theTable.setColumnSelectionAllowed(false);
		theTable.setCellSelectionEnabled(false);
		theTable.getSelectionModel().addListSelectionListener(this);
		theTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
		theCombo.setModel(theModel.getComboModel());
		theCombo.addItemListener(this);

		theTable.getColumnModel().getColumn(0).setMinWidth(30);
		//theTable.getColumnModel().getColumn(0).setResizable(false);

		//int lines = 2;
		//theTable.setRowHeight( theTable.getRowHeight() * lines);

		TableColumn column = theTable.getColumnModel().getColumn(1);
		column.setCellRenderer(new PropertyCellRenderer());
		setCurrEditor(new PropertyTable.PropertyCellEditor());

		for (int i = 0; i < theModel.getRowCount(); i++) {
			////System.out.println("Row "+i);
			//int lines = 1;

			//if (theModel.getValueAt(i, 1) instanceof SingleProperty)
				//lines = getNumLines(value);
			//theTable.setRowHeight(i, (lineWidth*lines)+2);
			//int heightWanted = (int)area.getPreferredSize().getHeight();
			//      if(heightWanted != theTable.getRowHeight(row));
			//    theTable.setRowHeight(row, heightWanted);
		}

		doChoiceBox();

		commentLabel.setFont(new Font("serif", Font.BOLD, 12));
		//theTable.setDefaultRenderer(String.class, new MultiLineCellRenderer());
		//theTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
	}

	public void setNameColumnWidth(int width)
	{
		//theTable.getColumnModel().getColumn(0).setMinWidth(width);
		//theTable.getColumnModel().getColumn(0).setMaxWidth(width);
		//theTable.getColumnModel().getColumn(0).setPreferredWidth(width);
		//theTable.getColumnModel().getColumn(0).setMaxWidth(width);
		//theTable.repaint();
	}

	private void doChoiceBox()
	{
		if (theModel.getNumGroups() == 0) {
			topPanel.removeAll();
			JLabel lab = new JLabel("");
			topPanel.setLayout(new BorderLayout());
			topPanel.add(lab, BorderLayout.CENTER);
		} else if (theModel.getNumGroups() == 1) {
			topPanel.removeAll();
			JLabel lab = new JLabel(theCombo.getModel().getElementAt(0).toString());
			topPanel.setLayout(new BorderLayout());
			topPanel.add(lab, BorderLayout.CENTER);
		} else {
			topPanel.removeAll();
			topPanel.setLayout(new BorderLayout());
			topPanel.add(theCombo, BorderLayout.CENTER);
		}
		this.revalidate();
	}

	public void stopEditing()
	{
		if (ce != null)
			ce.stopEditing();
	}

	public void setCurrEditor(PropertyTable.PropertyCellEditor ce)
	{
		TableColumn column = theTable.getColumnModel().getColumn(1);
		column.setCellEditor(ce);
		//if(this.ce != ce) System.out.println("THE CURREDITOR HAS CHANGED");

		this.ce = ce;
	}

	private PropertyTable.PropertyCellEditor ce;

	/** This method is called from within the constructor to
	 * initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is
	 * always regenerated by the Form Editor.
	 */
	private void initComponents()//GEN-BEGIN:initComponents
	{
		javax.swing.JPanel jPanel1;
		javax.swing.JPanel jPanel3;
		javax.swing.JScrollPane jScrollPane1;
		javax.swing.JSplitPane jSplitPane1;

		jPanel1 = new javax.swing.JPanel();
		jSplitPane1 = new javax.swing.JSplitPane();
		jScrollPane1 = new javax.swing.JScrollPane();
		jScrollPane1.getViewport().setBackground(Color.white);
		theTable = new JTable()
		{

			//This method is a fix from http://www.codeguru.com/java/articles/180.shtml by Zafir Anjum, cheers!
			//this is required because there is a bug in JTable where the
			//just saying tableScroll.setColumnHeader(null); does not work as it should
			//Unfortunately, it overrides a deprecated API, so let's hope they
			//sort it out by Java 5.0, nice one Sun...
			//Addition (6th December 2004) This is no longer needed,
			/*protected void configureEnclosingScrollPane()
			{
			    Container p = getParent();
			    if (p instanceof JViewport)
			    {
			        Container gp = p.getParent();
			        if (gp instanceof JScrollPane)
			        {
			            JScrollPane scrollPane = (JScrollPane)gp;
			            // Make certain we are the viewPort's view and not, for
			            // example, the rowHeaderView of the scrollPane -
			            // an implementor of fixed columns might do this.
			            JViewport viewport = scrollPane.getViewport();
			            if (viewport == null || viewport.getView() != this)
			            {
			                return;
			            }
			            //                scrollPane.setColumnHeaderView(getTableHeader());
			            scrollPane.getViewport().setBackingStoreEnabled(true);
			            scrollPane.setBorder(UIManager.getBorder("Table.scrollPaneBorder"));
			        }
			    }
			}*/

		};
		theTable.setModel(theModel);
		theTable.setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION);
		theTable.setRowSelectionAllowed(false);
		theTable.setColumnSelectionAllowed(false);
		theTable.setCellSelectionEnabled(true);
		jPanel3 = new javax.swing.JPanel();
		commentText = new javax.swing.JTextArea();
		commentLabel = new javax.swing.JLabel();
		topPanel = new javax.swing.JPanel();
		theCombo = new javax.swing.JComboBox();

		setLayout(new java.awt.BorderLayout());

		jPanel1.setLayout(new java.awt.BorderLayout());

		jSplitPane1.setBackground(new java.awt.Color(255, 255, 255));
		jSplitPane1.setBorder(null);
		jSplitPane1.setDividerSize(3);
		jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
		jSplitPane1.setResizeWeight(1.0);
		jSplitPane1.setOneTouchExpandable(true);
		jScrollPane1.setBackground(new java.awt.Color(255, 255, 255));
		jScrollPane1.setBorder(new javax.swing.border.LineBorder(java.awt.SystemColor.textInactiveText));
		jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		theTable.setModel(new javax.swing.table.DefaultTableModel(new Object[][] { { null, null, null, null }, { null, null, null, null },
				{ null, null, null, null }, { null, null, null, null } }, new String[] { "Title 1", "Title 2", "Title 3", "Title 4" }));
		theTable.setDoubleBuffered(true);
		theTable.setGridColor(new java.awt.Color(198, 197, 197));
		jScrollPane1.setViewportView(theTable);

		jSplitPane1.setLeftComponent(jScrollPane1);

		jPanel3.setLayout(new java.awt.BorderLayout());

		jPanel3.setBorder(new javax.swing.border.LineBorder(java.awt.SystemColor.inactiveCaption));
		jPanel3.setMinimumSize(new java.awt.Dimension(10, 75));
		jPanel3.setPreferredSize(new java.awt.Dimension(100, 75));
		commentText.setBackground(javax.swing.UIManager.getDefaults().getColor("Panel.background"));
		commentText.setColumns(1);
		commentText.setEditable(false);
		commentText.setLineWrap(true);
		commentText.setWrapStyleWord(true);
		commentText.setBorder(null);
		commentText.setDoubleBuffered(true);
		commentText.setFocusable(false);
		commentText.setMinimumSize(new java.awt.Dimension(100, 75));
		commentText.setPreferredSize(new java.awt.Dimension(100, 75));
		jPanel3.add(commentText, java.awt.BorderLayout.CENTER);

		jPanel3.add(commentLabel, java.awt.BorderLayout.NORTH);

		jSplitPane1.setRightComponent(jPanel3);

		jPanel1.add(jSplitPane1, java.awt.BorderLayout.CENTER);

		add(jPanel1, java.awt.BorderLayout.CENTER);

		topPanel.setLayout(new java.awt.BorderLayout());

		topPanel.add(theCombo, java.awt.BorderLayout.NORTH);

		add(topPanel, java.awt.BorderLayout.NORTH);

	}//GEN-END:initComponents

	public void valueChanged(ListSelectionEvent e)
	{
		SingleProperty selected = theModel.getSelectedProperty(theTable.getSelectedRow());

		if (selected != null) {
			commentLabel.setText(selected.getName());
			commentText.setText(selected.getComment());
		} else {
			commentLabel.setText("");
			commentText.setText("");
		}

		for (int i = 0; i < theModel.getRowCount(); i++) {
			int lines = 1;
			if (theModel.getValueAt(i, 1) instanceof FontColorProperty) {
				int height = ((FontColorProperty) theModel.getValueAt(i, 1)).getFontColorPair().f.getSize();
				height = Math.max(height, (lineWidth - 2));
				theTable.setRowHeight(i, (height * lines) + 4);
			} else if (theModel.getValueAt(i, 1) instanceof SingleProperty) {
				//lines = getNumLines(value);
				//int heightWanted = 
				//theTable.setRowHeight(i, (lineWidth*lines)+2);
			}
		}
	}

	public void tableChanged(TableModelEvent e)
	{
		CellEditor ce = theTable.getCellEditor();
		if (ce != null)
			ce.cancelCellEditing();
		theCombo.setModel(theModel.getComboModel());
		for (int i = 0; i < theModel.getRowCount(); i++) {
			////System.out.println("Row "+i);
			String value = theModel.getValueAt(i, 1).toString();
			int lines = 1;

			if (theModel.getValueAt(i, 1) instanceof FontColorProperty) {
				int height = ((FontColorProperty) theModel.getValueAt(i, 1)).getFontColorPair().f.getSize();

				height = Math.max(height, (lineWidth - 2));
				theTable.setRowHeight(i, (height * lines) + 4);
			} else if (theModel.getValueAt(i, 1) instanceof SingleProperty) {
				//lines = getNumLines(value);
				//theTable.setRowHeight(i, (lineWidth*lines)+2);
				//int heightWanted = (int)area.getPreferredSize().getHeight();
				///  if(heightWanted != theTable.getRowHeight(row));
				// theTable.setRowHeight(row, heightWanted);
			} else if (theModel.getValueAt(i, 1) instanceof MultipleProperty) {
				lines = getNumLines(value);
				theTable.setRowHeight(i, (lineWidth * lines) + 2);
			}

		}
		doChoiceBox();
		//theTable.s
	}

	public static int getNumLines(String str)
	{
		int count = 1;
		for (int i = 0; i < str.length(); i++) {
			char curr = str.charAt(i);
			if (curr == '\n')
				count++;
		}
		////System.out.println("count = "+count);
		return count;
	}

	public void itemStateChanged(ItemEvent e)
	{
		theModel.setCurrentGroup(theCombo.getSelectedIndex());
	}

	// Variables declaration - do not modify//GEN-BEGIN:variables
	javax.swing.JLabel commentLabel;
	javax.swing.JTextArea commentText;
	javax.swing.JComboBox theCombo;
	javax.swing.JTable theTable;
	javax.swing.JPanel topPanel;

	// End of variables declaration//GEN-END:variables

	public class PropertyCellEditor extends AbstractCellEditor implements TableCellEditor, CaretListener, KeyListener, ActionListener
	{
		JTextArea area; //For multiline SingleProperties
		JTextField field; //For single line SingleProperties
		boolean isMultiLine;
		int currentRow;
		BooleanProperty boolProp = null;
		FontColorProperty fcProp = null;
		ChoiceProperty chProp = null;
		ColourProperty colProp = null;

		public PropertyCellEditor()
		{
			//System.out.println("Instantiating new CELLEDITOR");
			area = new JTextArea();
			field = new JTextField();
			area.setLineWrap(true);
			area.setWrapStyleWord(true);
			area.setOpaque(true);
			field.setOpaque(true);
			field.addCaretListener(this);
			area.addCaretListener(this);
			area.addKeyListener(this);

			area.setBackground(Color.white);
			setCurrEditor(this);
		}

		public void stopEditing()
		{
			//System.out.println(field.getParent().toString());
			//if(field != null) System.out.println("This should stop the editing of the box " +field.getText());
			super.stopCellEditing();
		}

		public boolean shouldSelectCell(EventObject anEvent)
		{
			area.selectAll();
			field.selectAll();
			return true;
		}

		public Object getCellEditorValue()
		{
			if (boolProp != null) {
				//System.out.println("getting boolean cell editor value");
				boolProp.removeListenerFromEditor(this);
				return boolProp.getEditorValue();
			}
			if (fcProp != null) {
				//System.out.println("getting font colour cell editor value");
				fcProp.removeListenerFromEditor(this);
				return fcProp.getEditorValue();
			}
			if (chProp != null) {
				//System.out.println("getting choice cell editor value");
				chProp.removeListenerFromEditor(this);
				return chProp.getEditorValue();
			}
			if (colProp != null) {
				colProp.removeListenerFromEditor(this);
				return colProp.getEditorValue();
			}
			if (isMultiLine)
				return area.getText();
			else
				return field.getText();
		}

		public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)
		{
			//System.out.println("Calling getTableCellEditorComponent()");
			currentRow = row;
			boolProp = null;
			fcProp = null;
			chProp = null;
			colProp = null;
			if (value instanceof BooleanProperty) {
				boolProp = (BooleanProperty) value;
				boolProp.addListenerToEditor(this);
				return boolProp.getTableCellEditorComponent(table, value, isSelected, row, column);
			} else if (value instanceof FontColorProperty) {
				fcProp = (FontColorProperty) value;
				fcProp.addListenerToEditor(this);
				return fcProp.getTableCellEditorComponent(table, value, isSelected, row, column);
			} else if (value instanceof ChoiceProperty) {
				chProp = (ChoiceProperty) value;
				chProp.addListenerToEditor(this);
				return chProp.getTableCellEditorComponent(table, value, isSelected, row, column);
			} else if (value instanceof ColourProperty) {
				colProp = (ColourProperty) value;
				colProp.addListenerToEditor(this);
				return colProp.getTableCellEditorComponent(table, value, isSelected, row, column);
			} else if (value instanceof SingleProperty) {

				SingleProperty sp = (SingleProperty) value;
				if (!sp.isMultiline()) {
					if (!sp.isEnabled()) {/*
											area.setBackground(new Color(250,250,250));
											area.setForeground(Color.darkGray);
											field.setBackground(new Color(250,250,250));
											field.setForeground(Color.darkGray);
											*/
						field.setEnabled(false);
						area.setEnabled(false);
						field.setEditable(false);
						area.setEditable(false);
						field.setCaretColor(Color.white);
						area.setCaretColor(Color.white);
					} else {
						field.setEnabled(true);
						area.setEnabled(true);
						field.setEditable(true);
						area.setEditable(true);
						field.setCaretColor(Color.black);
						field.setCaretColor(Color.black);
					}
					field.setFont(table.getFont());
					field.setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
					field.setForeground(UIManager.getColor("Table.focusCellForeground"));
					field.setBackground(UIManager.getColor("Table.focusCellBackground"));
					field.setMargin(new Insets(0, 2, 4, 2));
					field.setText((value == null) ? "" : value.toString());
					isMultiLine = false;
					return field;
				} else {
					if (!sp.isEnabled()) {/*
											area.setBackground(new Color(250,250,250));
											area.setForeground(Color.darkGray);
											field.setBackground(new Color(250,250,250));
											field.setForeground(Color.darkGray);
											*/
						field.setEnabled(false);
						area.setEnabled(false);
						field.setEditable(false);
						area.setEditable(false);
						field.setCaretColor(Color.white);
						area.setCaretColor(Color.white);
					} else {
						field.setEnabled(true);
						area.setEnabled(true);
						field.setEditable(true);
						area.setEditable(true);
						field.setCaretColor(Color.black);
						area.setCaretColor(Color.black);
					}
					area.setFont(table.getFont());
					area.setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
					area.setForeground(UIManager.getColor("Table.focusCellForeground"));
					area.setBackground(UIManager.getColor("Table.focusCellBackground"));
					area.setMargin(new Insets(0, 2, 4, 2));
					area.setText((value == null) ? "" : value.toString());
					theTable.setEditingRow(row);
					isMultiLine = true;
					return area;
				}
			} else if (value instanceof MultipleProperty) {
				MultipleProperty sp = (MultipleProperty) value;
				if (sp.getProperty(0) instanceof BooleanProperty) {
					boolProp = (BooleanProperty) sp.getProperty(0);
					boolProp.addListenerToEditor(this);
					return boolProp.getTableCellEditorComponentMulti(table, value, isSelected, row, column, sp.allTheSame());
				} else if (sp.getProperty(0) instanceof FontColorProperty) {
					fcProp = (FontColorProperty) sp.getProperty(0);
					fcProp.addListenerToEditor(this);
					return fcProp.getTableCellEditorComponentMulti(table, value, isSelected, row, column, sp.allTheSame());
				} else if (sp.getProperty(0) instanceof ChoiceProperty) {
					chProp = (ChoiceProperty) sp.getProperty(0);
					chProp.addListenerToEditor(this);
					return chProp.getTableCellEditorComponentMulti(table, value, isSelected, row, column, sp.allTheSame());
				} else if (sp.getProperty(0) instanceof ColourProperty) {
					colProp = (ColourProperty) sp.getProperty(0);
					colProp.addListenerToEditor(this);
					return colProp.getTableCellEditorComponentMulti(table, value, isSelected, row, column, sp.allTheSame());
				}

				if (!sp.isMultiline()) {
					field.setFont(table.getFont());
					field.setForeground(Color.lightGray);
					field.setBackground(UIManager.getColor("Table.focusCellBackground"));
					field.setForeground(Color.lightGray);
					if (!sp.allTheSame())
						field.setBackground(new Color(240, 240, 240));
					field.setMargin(new Insets(0, 2, 4, 2));
					field.setText((value == null) ? "" : value.toString());
					isMultiLine = false;
					return field;
				} else {
					area.setFont(table.getFont());
					area.setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
					area.setForeground(Color.lightGray);
					area.setBackground(UIManager.getColor("Table.focusCellBackground"));
					area.setForeground(Color.lightGray);
					if (!sp.allTheSame())
						area.setBackground(new Color(240, 240, 240));
					area.setMargin(new Insets(0, 2, 4, 2));
					area.setText((value == null) ? "" : value.toString());
					isMultiLine = true;
					return area;
				}
			} else
				return new JLabel("ERROR");
		}

		public void caretUpdate(CaretEvent e)
		{

			//System.out.println("caret update");
			if (e.getSource() == field) {
				field.getCaret().setVisible(true);
			}
			if (e.getSource() == area) {
				//System.out.println("area");
				area.getCaret().setVisible(true);
				//theTable.setRowHeight(currentRow, (area.getLineCount()*lineWidth)+2);
				int heightWanted = (int) area.getPreferredSize().getHeight();
				if (heightWanted != theTable.getRowHeight(currentRow))
					theTable.setRowHeight(currentRow, heightWanted);

			}
		}

		public void keyPressed(KeyEvent e)
		{
			if (e.getSource() == area) {
				try {
					int startOfLastLine = area.getLineStartOffset(area.getLineCount() - 1);
					int endOfFirstLine = area.getLineEndOffset(0);
					int currentPosition = area.getCaretPosition();
					if (e.getKeyCode() == KeyEvent.VK_UP) {
						if (currentPosition < endOfFirstLine) {
							//System.out.println("should move up");
							this.stopCellEditing();

							int newPosition = (currentRow - 1);
							if (newPosition < 0)
								newPosition = theTable.getRowCount() - 1;
							theTable.getSelectionModel().setSelectionInterval(newPosition, newPosition);
						} else if (area.getText().length() == 0) {
							this.stopCellEditing();

							int newPosition = (currentRow - 1);
							if (newPosition < 0)
								newPosition = theTable.getRowCount() - 1;
							theTable.getSelectionModel().setSelectionInterval(newPosition, newPosition);
						}
					} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
						if (currentPosition > startOfLastLine) {
							//System.out.println("should move down");
							this.stopCellEditing();
							int newPosition = (currentRow + 1) % theTable.getRowCount();
							theTable.getSelectionModel().setSelectionInterval(newPosition, newPosition);
						} else if (area.getText().length() == 0) {
							this.stopCellEditing();
							int newPosition = (currentRow + 1) % theTable.getRowCount();
							theTable.getSelectionModel().setSelectionInterval(newPosition, newPosition);
						}
					}
				} catch (BadLocationException ex) {
				}
			}
		}

		public void keyReleased(KeyEvent e)
		{
		}

		public void keyTyped(KeyEvent e)
		{
		}

		public void actionPerformed(ActionEvent e)
		{
			stopCellEditing();
		}

	}

	//Uses different renderers for different types of property
	class PropertyCellRenderer implements TableCellRenderer
	{
		JTextArea area;
		JTextField field;

		public PropertyCellRenderer()
		{
			area = new JTextArea();
			field = new JTextField();
			area.setLineWrap(false);
			area.setOpaque(true);
			field.setOpaque(true);
			//area.setWrapStyleWord(f);
		}

		public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
		{
			////System.out.println("rendering "+value.toString());
			if (isSelected) {
				area.setForeground(table.getSelectionForeground());
				area.setBackground(table.getSelectionBackground());
				field.setForeground(table.getSelectionForeground());
				field.setBackground(table.getSelectionBackground());
			} else {
				area.setForeground(table.getForeground());
				area.setBackground(Color.white);
				field.setForeground(table.getForeground());
				field.setBackground(Color.white);
			}

			if (value instanceof SingleProperty) {
				SingleProperty sp = (SingleProperty) value;
				Component c = sp.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
				if (c != null)
					return c;

				if (!sp.isEnabled()) {/*
										   area.setBackground(new Color(250,250,250));
										   area.setForeground(Color.darkGray);
										   field.setBackground(new Color(250,250,250));
										   field.setForeground(Color.darkGray);
										*/
					field.setEnabled(false);
					area.setEnabled(false);
					field.setEditable(false);
					area.setEditable(false);
					field.setCaretColor(Color.white);
					area.setCaretColor(Color.white);
				} else {
					field.setEnabled(true);
					area.setEnabled(true);
					field.setEditable(true);
					area.setEditable(true);
					field.setCaretColor(Color.black);
					area.setCaretColor(Color.black);
				}
				////System.out.println("Rendering: "+sp.getName()+" "+sp.toString()+ " multiline = "+sp.isMultiline());
				if (!sp.isMultiline()) {
					field.setFont(table.getFont());

					if (hasFocus) {
						field.setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
						if (table.isCellEditable(row, column)) {
							field.setForeground(UIManager.getColor("Table.focusCellForeground"));
							field.setBackground(UIManager.getColor("Table.focusCellBackground"));
						}
					} else {
						field.setBorder(new EmptyBorder(1, 2, 2, 1));
					}
					field.setMargin(new Insets(0, 2, 4, 2));
					field.setText((value == null) ? "" : value.toString());
					return field;
				} else {
					area.setFont(table.getFont());

					if (hasFocus) {
						area.setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
						if (table.isCellEditable(row, column)) {
							area.setForeground(UIManager.getColor("Table.focusCellForeground"));
							area.setBackground(UIManager.getColor("Table.focusCellBackground"));
						}
					} else {
						area.setBorder(new EmptyBorder(0, 2, 2, 1));
					}
					//area.setBackground( Color.yellow);
					area.setMargin(new Insets(0, 2, 4, 2));
					area.setText((value == null) ? "" : value.toString());

					int heightWanted = (int) area.getPreferredSize().getHeight();
					if (heightWanted != theTable.getRowHeight(row))
						theTable.setRowHeight(row, heightWanted);
					return area;
				}
			} else if (value instanceof MultipleProperty) {
				MultipleProperty sp = (MultipleProperty) value;
				////System.out.println("Rendering:mult "+sp.getName()+" "+sp.toString()+ " multiline = "+sp.isMultiline());
				Component c = sp.getTableCellRendererComponentMulti(table, value, isSelected, hasFocus, row, column);
				if (c != null)
					return c;

				if (!sp.isMultiline()) {
					field.setFont(table.getFont());

					if (hasFocus) {
						field.setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
						if (table.isCellEditable(row, column)) {
							field.setForeground(Color.lightGray);
							field.setBackground(UIManager.getColor("Table.focusCellBackground"));
						}
					} else {
						field.setBorder(new EmptyBorder(1, 2, 2, 1));
					}

					if (!sp.allTheSame()) {
						field.setBackground(new Color(240, 240, 240));
						field.setForeground(Color.lightGray);
					} else {
						field.setForeground(Color.black);
					}
					field.setMargin(new Insets(0, 2, 4, 2));
					field.setText((value == null) ? "" : value.toString());
					return field;
				} else {
					area.setFont(table.getFont());

					if (hasFocus) {
						area.setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
						if (table.isCellEditable(row, column)) {
							area.setForeground(Color.lightGray);
							area.setBackground(UIManager.getColor("Table.focusCellBackground"));
						}
					} else {
						area.setBorder(new EmptyBorder(0, 2, 2, 1));
					}

					if (!sp.allTheSame()) {
						area.setBackground(new Color(240, 240, 240));
						area.setForeground(Color.lightGray);
					} else {
						area.setForeground(Color.black);
					}
					//area.setBackground(Color.yellow);
					area.setMargin(new Insets(0, 2, 4, 2));
					area.setText((value == null) ? "" : value.toString());
					return area;
				}
			} else {
				field.setFont(table.getFont());

				if (hasFocus) {
					field.setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
					if (table.isCellEditable(row, column)) {
						field.setForeground(UIManager.getColor("Table.focusCellForeground"));
						field.setBackground(UIManager.getColor("Table.focusCellBackground"));
					}
				} else {
					field.setBorder(new EmptyBorder(1, 2, 2, 1));
				}
				field.setMargin(new Insets(0, 2, 4, 2));
				field.setText((value == null) ? "" : value.toString());
				return field;
			}
		}
	}

}
