/*******************************************************************************
 * Copyright (c) 2000, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.tests.junit;

import junit.framework.*;
import junit.textui.*;
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.graphics.*;

/**
 * Automated Test Suite for class org.eclipse.swt.widgets.TableItem
 *
 * @see org.eclipse.swt.widgets.TableItem
 */
public class Test_org_eclipse_swt_widgets_TableItem extends Test_org_eclipse_swt_widgets_Item {

public Test_org_eclipse_swt_widgets_TableItem(String name) {
	super(name);
}

public static void main(String[] args) {
	TestRunner.run(suite());
}

protected void setUp() {
	super.setUp();
	makeCleanEnvironment();
}

protected void tearDown() {
	super.tearDown();
}

public void test_ConstructorLorg_eclipse_swt_widgets_TableI() {
	try {
		new TableItem(null, SWT.NULL);
		fail("No exception thrown for parent == null");
	}
	catch (IllegalArgumentException e) {
	}
	
	for (int i=0; i<10; i++) {
		new TableItem(table, SWT.NONE);	
	}
	assertEquals(11, table.getItemCount());
	new TableItem(table, SWT.NONE, 5);	
	assertEquals(12, table.getItemCount());
}

public void test_ConstructorLorg_eclipse_swt_widgets_TableII() {
	try {
		new TableItem(table, SWT.NONE, 5);
		fail("No exception thrown for illegal index argument");
	}
	catch (IllegalArgumentException e) {
	}
}

public void test_getBackground() {
	// tested in test_setBackgroundLorg_eclipse_swt_graphics_Color
}

public void test_getBackgroundI() {
	// tested in test_setBackgroundILorg_eclipse_swt_graphics_Color
}

public void test_getBoundsI() {
	Image image = images[0];
	Rectangle bounds;
	Rectangle bounds2;
	
	// no columns
 	bounds = tableItem.getBounds(0);
	assertTrue(":1a:", bounds.x > 0 && bounds.height > 0);
	bounds = tableItem.getBounds(-1);
	assertTrue(":1b:", bounds.equals(new Rectangle(0, 0, 0, 0)));	
 	bounds = tableItem.getBounds(1);
	assertTrue(":1c:", bounds.equals(new Rectangle(0, 0, 0, 0)));
	
	tableItem.setText("hello");
	bounds = tableItem.getBounds(0);
	assertTrue(":1d:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0);
	tableItem.setText("");
	bounds2 = tableItem.getBounds(0);
	assertTrue(":1e:", bounds2.x > 0 && bounds2.height > 0);
	//assertTrue(":1f:", bounds2.width < bounds.width); // TODO doesn't shrink?
	
	//
	makeCleanEnvironment();
	
	tableItem.setImage(image);
	bounds = tableItem.getBounds(0);
	assertTrue(":1g:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0);
	tableItem.setImage((Image)null);
	bounds2 = tableItem.getBounds(0);
	assertTrue(":1h:", bounds2.x > 0 && bounds2.height > 0);
//	assertTrue(":1i:", bounds2.width > bounds.width); // TODO once an image is added the space for it is always there
 	
	//
	makeCleanEnvironment();
	
	tableItem.setText("hello");
	bounds = tableItem.getBounds(0);
	tableItem.setImage(image);
	bounds2 = tableItem.getBounds(0);
	assertTrue(":1j:", bounds2.x > 0 && bounds2.height > 0);
	assertTrue(":1k:", bounds2.width > bounds.width);
	
	// no columns and CHECK style
	Table table2 = new Table(shell, SWT.CHECK);
	TableItem tableItem2 = new TableItem(table2, SWT.NONE);
	
	bounds = tableItem2.getBounds(0);
	assertTrue(":2a:", bounds.x > 0 && bounds.height > 0);
	bounds = tableItem2.getBounds(-1);
	assertTrue(":2b:", bounds.equals(new Rectangle(0, 0, 0, 0)));	
 	bounds = tableItem2.getBounds(1);
	assertTrue(":2c:", bounds.equals(new Rectangle(0, 0, 0, 0)));
	
	tableItem2.setText("hello");
	bounds = tableItem2.getBounds(0);
	assertTrue(":2d:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0);
	tableItem2.setText("");
	bounds2 = tableItem2.getBounds(0);
	assertTrue(":2e:", bounds2.x > 0 && bounds2.height > 0);
	//assertTrue(":2f:", bounds2.width < bounds.width); // TODO doesn't shrink?
	
	table2.dispose();
	table2 = new Table(shell, SWT.CHECK);
	tableItem2 = new TableItem(table2, SWT.NONE);
	
	tableItem2.setImage(image);
	bounds = tableItem2.getBounds(0);
	assertTrue(":2g:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0);
	tableItem2.setImage((Image)null);
	bounds2 = tableItem2.getBounds(0);
	assertTrue(":2h:", bounds2.x > 0 && bounds2.height > 0);
	//assertTrue(":2i:", bounds2.width < bounds.width);  // TODO once an image is added the space for it is always there
	
	table2.dispose();
	table2 = new Table(shell, SWT.CHECK);
	tableItem2 = new TableItem(table2, SWT.NONE);
	
	tableItem2.setText("hello");
	bounds = tableItem2.getBounds(0);
	tableItem2.setImage(image);
	bounds2 = tableItem2.getBounds(0);
	assertTrue(":2j:", bounds2.x > 0 && bounds2.height > 0);
	assertTrue(":2k:", bounds2.width > bounds.width);
	
	//
	makeCleanEnvironment();

	// with columns
	
	TableColumn column0 = new TableColumn(table, SWT.LEFT);
	TableColumn column1 = new TableColumn(table, SWT.CENTER);
	
	bounds = tableItem.getBounds(0);
	assertTrue(":3a:", bounds.x > 0 && bounds.height > 0 && bounds.width == 0);
	bounds = tableItem.getBounds(1);
	assertTrue(":3b:", /*bounds.x > 0 &&*/ bounds.height > 0 && bounds.width == 0); // TODO bounds.x == 0 Is this right?
	bounds = tableItem.getBounds(-1);
	assertTrue(":3c:", bounds.equals(new Rectangle(0, 0, 0, 0)));	
 	bounds = tableItem.getBounds(2);
	assertTrue(":3d:", bounds.equals(new Rectangle(0, 0, 0, 0)));
	
	column0.setWidth(100);
	bounds = tableItem.getBounds(0);
	assertTrue(":3e:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0 && bounds.width < 100);
	bounds = tableItem.getBounds(1);
	assertTrue(":3f:", bounds.x >= 100 && bounds.height > 0 && bounds.width == 0);
	
	column1.setWidth(200);
	bounds = tableItem.getBounds(0);
	assertTrue(":3g:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0 && bounds.width < 100);
	bounds = tableItem.getBounds(1);
	assertTrue(":3h:", bounds.x >= 100 && bounds.height > 0 && bounds.width == 200);
	
	tableItem.setText(new String[] {"hello", "world"});
	bounds = tableItem.getBounds(0);
	assertTrue(":3i:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0 && bounds.width < 100);
	bounds = tableItem.getBounds(1);
	assertTrue(":3j:", bounds.x >= 100 && bounds.height > 0 && bounds.width  == 200);
	tableItem.setText(new String[] {"", ""});
	bounds = tableItem.getBounds(0);
	assertTrue(":3k:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0 && bounds.width < 100);
	bounds = tableItem.getBounds(1);
	assertTrue(":3l:", bounds.x >= 100 && bounds.height > 0 && bounds.width  == 200);
	
	//
	makeCleanEnvironment();
	column0 = new TableColumn(table, SWT.LEFT);
	column1 = new TableColumn(table, SWT.CENTER);
	column0.setWidth(100);
	column1.setWidth(200);
	
	tableItem.setImage(new Image[] {image, image});
	bounds = tableItem.getBounds(0);
	assertTrue(":3m:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0 && bounds.width < 100);
	bounds = tableItem.getBounds(1);
	assertTrue(":3n:", bounds.x >= 100 && bounds.height > 0 && bounds.width  == 200);
 	tableItem.setImage(new Image[] {null, null});
	bounds = tableItem.getBounds(0);
	assertTrue(":3o:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0 && bounds.width < 100);
	bounds = tableItem.getBounds(1);
	assertTrue(":3p:", bounds.x >= 100 && bounds.height > 0 && bounds.width  == 200);
	
	//
	makeCleanEnvironment();
	column0 = new TableColumn(table, SWT.LEFT);
	column1 = new TableColumn(table, SWT.CENTER);
	column0.setWidth(100);
	column1.setWidth(200);
	
	tableItem.setText(new String[] {"hello", "world"});
	tableItem.setImage(new Image[] {null, null});
	bounds = tableItem.getBounds(0);
	assertTrue(":3q:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0 && bounds.width < 100);
	bounds = tableItem.getBounds(1);
	assertTrue(":3r:", bounds.x > 0 && bounds.height > 0 && bounds.width  == 200);
	
	//
	makeCleanEnvironment();
	
	tableItem.setText("hello");
	TableColumn column = new TableColumn(table, SWT.RIGHT);
	bounds = tableItem.getBounds(0);
	assertTrue(":3s:", bounds.x > 0 && bounds.height > 0 && bounds.width  == 0);
	
	// with columns and CHECK style
	table2.dispose();
	table2 = new Table(shell, SWT.CHECK);
	tableItem2 = new TableItem(table2, SWT.NONE);
	column0 = new TableColumn(table2, SWT.LEFT);
	column1 = new TableColumn(table2, SWT.CENTER);
	
	bounds = tableItem2.getBounds(0);
	assertTrue(":4a:", bounds.x > 0 && bounds.height > 0 && bounds.width == 0);
	bounds = tableItem2.getBounds(1);
	assertTrue(":4b:", /*bounds.x > 0 &&*/ bounds.height > 0 && bounds.width == 0); // TODO bounds.x == 0 Is this right?
	bounds = tableItem2.getBounds(-1);
	assertTrue(":4c:", bounds.equals(new Rectangle(0, 0, 0, 0)));	
 	bounds = tableItem2.getBounds(2);
	assertTrue(":4d:", bounds.equals(new Rectangle(0, 0, 0, 0)));
	
	column0.setWidth(100);
	bounds = tableItem2.getBounds(0);
	assertTrue(":4e:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0 && bounds.width < 100);
	bounds = tableItem2.getBounds(1);
	assertTrue(":4f:", bounds.x >= 100 && bounds.height > 0 && bounds.width == 0);
	
	column1.setWidth(200);
	bounds = tableItem2.getBounds(0);
	assertTrue(":4g:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0 && bounds.width < 100);
	bounds = tableItem2.getBounds(1);
	assertTrue(":4h:", bounds.x >= 100 && bounds.height > 0 && bounds.width == 200);
	
	tableItem2.setText(new String[] {"hello", "world"});
	bounds = tableItem2.getBounds(0);
	assertTrue(":4i:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0 && bounds.width < 100);
	bounds = tableItem2.getBounds(1);
	assertTrue(":4j:", bounds.x >= 100 && bounds.height > 0 && bounds.width  == 200);
	tableItem2.setText(new String[] {"", ""});
	bounds = tableItem2.getBounds(0);
	assertTrue(":4k:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0 && bounds.width < 100);
	bounds = tableItem2.getBounds(1);
	assertTrue(":4l:", bounds.x >= 100 && bounds.height > 0 && bounds.width  == 200);
	
	//
	table2.dispose();
	table2 = new Table(shell, SWT.CHECK);
	tableItem2 = new TableItem(table2, SWT.NONE);
	column0 = new TableColumn(table2, SWT.LEFT);
	column1 = new TableColumn(table2, SWT.CENTER);
	column0.setWidth(100);
	column1.setWidth(200);
	
	tableItem2.setImage(new Image[] {image, image});
	bounds = tableItem2.getBounds(0);
	assertTrue(":4m:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0 && bounds.width < 100);
	bounds = tableItem2.getBounds(1);
	assertTrue(":4n:", bounds.x >= 100 && bounds.height > 0 && bounds.width  == 200);
 	tableItem2.setImage(new Image[] {null, null});
	bounds = tableItem2.getBounds(0);
	assertTrue(":4o:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0 && bounds.width < 100);
	bounds = tableItem2.getBounds(1);
	assertTrue(":4p:", bounds.x >= 100 && bounds.height > 0 && bounds.width  == 200);
	
	//
	table2.dispose();
	table2 = new Table(shell, SWT.CHECK);
	tableItem2 = new TableItem(table2, SWT.NONE);
	column0 = new TableColumn(table2, SWT.LEFT);
	column1 = new TableColumn(table2, SWT.CENTER);
	column0.setWidth(100);
	column1.setWidth(200);
	
	tableItem2.setText(new String[] {"hello", "world"});
	tableItem2.setImage(new Image[] {null, null});
	bounds = tableItem2.getBounds(0);
	assertTrue(":4q:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0 && bounds.width < 100);
	bounds = tableItem2.getBounds(1);
	assertTrue(":4r:", bounds.x >= 100 && bounds.height > 0 && bounds.width  == 200);
	
	//
	table2.dispose();
	table2 = new Table(shell, SWT.CHECK);
	tableItem2 = new TableItem(table2, SWT.NONE);
	
	tableItem2.setText("hello");
	column = new TableColumn(table2, SWT.RIGHT);
	bounds = tableItem2.getBounds(0);
	assertTrue(":4s:", bounds.x > 0 && bounds.height > 0 && bounds.width  == 0);
}

public void test_getChecked() {
	// tested in test_setCheckedZ
}

public void test_getFont() {
	// tested in test_setFontLorg_eclipse_swt_graphics_Font
}

public void test_getFontI() {
	// tested in test_setFontILorg_eclipse_swt_graphics_Font
}

public void test_getForeground() {
	// tested in test_setForegroundLorg_eclipse_swt_graphics_Color
}

public void test_getForegroundI() {
	// tested in test_setForegroundILorg_eclipse_swt_graphics_Color
}

public void test_getGrayed() {
	// tested in test_setGrayedZ
}

public void test_getImageBoundsI() {
/**
 * Test without item image
 */
	Rectangle bounds;
	Table table2 = new Table(shell, SWT.CHECK);
	TableItem tableItem2 = new TableItem(table2, SWT.NULL);
	
	assertEquals(new Rectangle(0, 0, 0, 0), tableItem.getImageBounds(-1));
	
	bounds = tableItem.getImageBounds(0);
	assertTrue(":b:", bounds.width == 0);
	
	assertEquals(new Rectangle(0, 0, 0, 0), tableItem.getImageBounds(1));
	
	assertEquals(new Rectangle(0, 0, 0, 0), tableItem2.getImageBounds(-1));
	
	bounds = tableItem2.getImageBounds(0);
	assertTrue(":e:", bounds.width == 0);
	
	assertEquals(new Rectangle(0, 0, 0, 0), tableItem2.getImageBounds(1));
 	//
	makeCleanEnvironment();
	
	Image image = images[0];	
	int imageWidth = image.getBounds().width;
	int imageHeight;
	
	tableItem.setImage(0, image);
	imageHeight = table.getItemHeight() - table.getGridLineWidth();
	assertEquals(new Rectangle(0, 0, 0, 0), tableItem.getImageBounds(-1));
	
	bounds = tableItem.getImageBounds(0);
//	assertTrue(":b:", bounds.x > 0 && bounds.width == imageWidth && bounds.height == imageHeight);	
// 	assertEquals(new Rectangle(0, 0, 0, 0), tableItem.getImageBounds(1));	


	//
	makeCleanEnvironment();	
	
	table2.dispose();
	table2 = new Table(shell, SWT.CHECK);
	tableItem2.dispose();
	tableItem2 = new TableItem(table2, SWT.NULL);
	Rectangle imageBounds = image.getBounds();
	imageWidth = imageBounds.width; 	tableItem2.setImage(0, image);
	imageHeight = table2.getItemHeight() - table2.getGridLineWidth();
	assertEquals(new Rectangle(0, 0, 0, 0), tableItem2.getImageBounds(-1));
	
	bounds = tableItem2.getImageBounds(0);	// bounds.width should be check box width if they are wider than image
//	assertTrue(":b:", bounds.x > 0 && bounds.width > 0 && bounds.height == imageHeight);
// 	assertEquals(new Rectangle(0, 0, 0, 0), tableItem2.getImageBounds(1));	


	//
	makeCleanEnvironment();

	table2.dispose();
	table2 = new Table(shell, SWT.CHECK);
	tableItem2.dispose();
	tableItem2 = new TableItem(table2, SWT.NULL);
	image = images[1];
	imageBounds = image.getBounds();
	imageWidth = imageBounds.width;
 	tableItem2.setImage(0, image);
	imageHeight = table2.getItemHeight() - table2.getGridLineWidth();
	assertEquals(new Rectangle(0, 0, 0, 0), tableItem2.getImageBounds(-1));
 	bounds = tableItem2.getImageBounds(0);	// bounds.width should be check box width if check box is wider than image
//	assertTrue(":b:", bounds.x > 0 && bounds.width > 0 && bounds.height == imageHeight);
 	assertEquals(new Rectangle(0, 0, 0, 0), tableItem2.getImageBounds(1));
}

public void test_getImageI() {
	// tested in test_setImageILorg_eclipse_swt_graphics_Image
}

public void test_getImageIndent() {
	warnUnimpl("Test test_getImageIndent not written");
}

public void test_getParent() {
	assertEquals(table, tableItem.getParent());
}

public void test_getTextI() {
	// tested in test_setTextILJava_lang_String
}

public void test_setBackgroundILorg_eclipse_swt_graphics_Color() {
	Display display = tableItem.getDisplay();
	Color red = display.getSystemColor(SWT.COLOR_RED);
	Color blue = display.getSystemColor(SWT.COLOR_BLUE);
	
	// no columns
	assertEquals(table.getBackground(), tableItem.getBackground(0));
	assertEquals(tableItem.getBackground(), tableItem.getBackground(0));
	tableItem.setBackground(0, red);
	assertEquals(red, tableItem.getBackground(0));
	
	// index beyond range - no error
	tableItem.setBackground(10, red);
	assertEquals(tableItem.getBackground(), tableItem.getBackground(10));
	
	// with columns
	TableColumn column1 = new TableColumn(table, SWT.LEFT);
	TableColumn column2 = new TableColumn(table, SWT.LEFT);
	
	// index beyond range - no error
	tableItem.setBackground(10, red);
	assertEquals(tableItem.getBackground(), tableItem.getBackground(10));
	
	tableItem.setBackground(0, red);
	assertEquals(red, tableItem.getBackground(0));
	tableItem.setBackground(0, null);
	assertEquals(table.getBackground(),tableItem.getBackground(0));

	tableItem.setBackground(0, blue);
	tableItem.setBackground(red);
	assertEquals(blue, tableItem.getBackground(0));
	
	tableItem.setBackground(0, null);
	assertEquals(red, tableItem.getBackground(0));
	
	tableItem.setBackground(null);
	assertEquals(table.getBackground(),tableItem.getBackground(0));
	
	try { 
		Color color = new Color(display, 255, 0, 0);
		color.dispose();
		tableItem.setBackground(color);
		fail("No exception thrown for color disposed");		
	} catch (IllegalArgumentException e) {
	}
}

public void test_setBackgroundLorg_eclipse_swt_graphics_Color() {
	Color color = new Color(tableItem.getDisplay(), 255, 0, 0);
	tableItem.setBackground(color);
	assertEquals(color, tableItem.getBackground());
	tableItem.setBackground(null);
	assertEquals(table.getBackground(),tableItem.getBackground());
	color.dispose();
	try { 
		tableItem.setBackground(color);
		fail("No exception thrown for color disposed");		
	} catch (IllegalArgumentException e) {
	}
}

public void test_setCheckedZ() {
	assertEquals(false, tableItem.getChecked());
	
	tableItem.setChecked(true);
	assertEquals(false, tableItem.getChecked());
 	Table t = new Table(shell, SWT.CHECK);
	TableItem ti = new TableItem(t, SWT.NULL);
	ti.setChecked(true);
	assertTrue(ti.getChecked());
	
	ti.setChecked(false);
	assertEquals(false, ti.getChecked());
	t.dispose();
}

public void test_setFontLorg_eclipse_swt_graphics_Font() {
	Display display = tableItem.getDisplay();
	Font font = tableItem.getFont();
	tableItem.setFont(font);
	assertTrue(font.equals(tableItem.getFont()));
	
	font = new Font(display, SwtJunit.testFontName, 10, SWT.NORMAL);
	tableItem.setFont(font);
	assertTrue(font.equals( tableItem.getFont()));

	tableItem.setFont(null);
	assertTrue(table.getFont().equals(tableItem.getFont()));
	
	font.dispose();
	try {
		tableItem.setFont(font);
		tableItem.setFont(null);
		fail("No exception thrown for disposed font");
	} catch (IllegalArgumentException e) {
	}
}

public void test_setFontILorg_eclipse_swt_graphics_Font() {
	Display display = tableItem.getDisplay();
	Font font = new Font(display, SwtJunit.testFontName, 10, SWT.NORMAL);
	
	// no columns
	assertTrue(table.getFont().equals(tableItem.getFont(0)));
	assertTrue(tableItem.getFont().equals(tableItem.getFont(0)));
	tableItem.setFont(0, font);
	assertTrue(font.equals(tableItem.getFont(0)));
	
	// index beyond range - no error
	tableItem.setFont(10, font);
	assertTrue(tableItem.getFont().equals(tableItem.getFont(10)));
	
	// with columns
	TableColumn column1 = new TableColumn(table, SWT.LEFT);
	TableColumn column2 = new TableColumn(table, SWT.LEFT);
	
	// index beyond range - no error
	tableItem.setFont(10, font);
	assertTrue(tableItem.getFont().equals(tableItem.getFont(10)));
	
	tableItem.setFont(0, font);
	assertTrue(font.equals(tableItem.getFont(0)));
	tableItem.setFont(0, null);
	assertTrue(table.getFont().equals(tableItem.getFont(0)));
	
	Font font2 = new Font(display, SwtJunit.testFontName, 20, SWT.NORMAL);
	
	tableItem.setFont(0, font);
	tableItem.setFont(font2);
	assertTrue(font.equals(tableItem.getFont(0)));
	
	tableItem.setFont(0, null);
	assertTrue(font2.equals(tableItem.getFont(0)));
	
	tableItem.setFont(null);
	assertTrue(table.getFont().equals(tableItem.getFont(0)));
	
	font.dispose();
	font2.dispose();
	
	try {
		tableItem.setFont(0, font);
		tableItem.setFont(0, null);
		fail("No exception thrown for disposed font");
	} catch (IllegalArgumentException e) {
	}
}

public void test_setForegroundILorg_eclipse_swt_graphics_Color() {
	Display display = tableItem.getDisplay();
	Color red = display.getSystemColor(SWT.COLOR_RED);
	Color blue = display.getSystemColor(SWT.COLOR_BLUE);
	
	// no columns
	assertEquals(table.getForeground(), tableItem.getForeground(0));
	assertEquals(tableItem.getForeground(), tableItem.getForeground(0));
	tableItem.setForeground(0, red);
	assertEquals(red, tableItem.getForeground(0));
	
	// index beyond range - no error
	tableItem.setForeground(10, red);
	assertEquals(tableItem.getForeground(), tableItem.getForeground(10));
	
	// with columns
	TableColumn column1 = new TableColumn(table, SWT.LEFT);
	TableColumn column2 = new TableColumn(table, SWT.LEFT);
	
	// index beyond range - no error
	tableItem.setForeground(10, red);
	assertEquals(tableItem.getForeground(), tableItem.getForeground(10));
	
	tableItem.setForeground(0, red);
	assertEquals(red, tableItem.getForeground(0));
	tableItem.setForeground(0, null);
	assertEquals(table.getForeground(),tableItem.getForeground(0));

	tableItem.setForeground(0, blue);
	tableItem.setForeground(red);
	assertEquals(blue, tableItem.getForeground(0));
	
	tableItem.setForeground(0, null);
	assertEquals(red, tableItem.getForeground(0));
	
	tableItem.setForeground(null);
	assertEquals(table.getForeground(),tableItem.getForeground(0));
	
	try { 
		Color color = new Color(display, 255, 0, 0);
		color.dispose();
		tableItem.setForeground(color);
		fail("No exception thrown for color disposed");		
	} catch (IllegalArgumentException e) {
	}
}

public void test_setForegroundLorg_eclipse_swt_graphics_Color() {
	Color color = new Color(tableItem.getDisplay(), 255, 0, 0);
	tableItem.setForeground(color);
	assertEquals(color, tableItem.getForeground());
	tableItem.setForeground(null);
	assertEquals(table.getForeground(),tableItem.getForeground());
	color.dispose();
	try { 
		tableItem.setForeground(color);
		fail("No exception thrown for color disposed");
	} catch (IllegalArgumentException e) {
	}
}

public void test_setGrayedZ() {
	Table newTable = new Table(shell, SWT.CHECK);
	TableItem tItem = new TableItem(newTable,0);
	assertEquals(false, tItem.getGrayed());
	tItem.setGrayed(true);
	assertTrue(tItem.getGrayed());
	tItem.setGrayed(false);
	assertEquals(false, tItem.getGrayed());
	newTable.dispose();
}

public void test_setImage$Lorg_eclipse_swt_graphics_Image() {
	assertNull(tableItem.getImage(1));	
 	tableItem.setImage(-1, null);		
	assertNull(tableItem.getImage(-1));	
		
	tableItem.setImage(0, images[0]);
	assertEquals(images[0], tableItem.getImage(0));	
 	String texts[] = new String[images.length];
	for (int i = 0; i < texts.length; i++) {
		texts[i] = String.valueOf(i);
	}
	
	//table.setText(texts);				// create enough columns for TableItem.setImage(Image[]) to work
	int columnCount = table.getColumnCount();
	if (columnCount < texts.length) {
		for (int i = columnCount; i < texts.length; i++){
			TableColumn column = new TableColumn(table, SWT.NONE);
		}
	}
	TableColumn[] columns = table.getColumns();
	for (int i = 0; i < texts.length; i++) {
		columns[i].setText(texts[i]);
	}
	tableItem.setImage(1, images[1]);
	assertEquals(images[1], tableItem.getImage(1));	
 	tableItem.setImage(images);
	for (int i = 0; i < images.length; i++) {
		assertEquals(images[i], tableItem.getImage(i));
	}
	try {
		tableItem.setImage((Image []) null);
		fail("No exception thrown for images == null");
	}
	catch (IllegalArgumentException e) {
	}
}

public void test_setImageILorg_eclipse_swt_graphics_Image() {
		// no columns
	assertEquals(null, tableItem.getImage(0));
	tableItem.setImage(0, images[0]);
	assertEquals(images[0], tableItem.getImage(0));
	
	// index beyond range - no error
	tableItem.setImage(10, images[0]);
	assertEquals(null, tableItem.getImage(10));
	
	// with columns
	TableColumn column1 = new TableColumn(table, SWT.LEFT);
	TableColumn column2 = new TableColumn(table, SWT.LEFT);
	
	// index beyond range - no error
	tableItem.setImage(10, images[0]);
	assertEquals(null, tableItem.getImage(10));
	
	tableItem.setImage(0, images[0]);
	assertEquals(images[0], tableItem.getImage(0));
	tableItem.setImage(0, null);
	assertEquals(null, tableItem.getImage(0));
	
	tableItem.setImage(0, images[0]);
	tableItem.setImage(images[1]);
	assertEquals(images[1], tableItem.getImage(0));
	
	tableItem.setImage(images[1]);
	tableItem.setImage(0, images[0]);
	assertEquals(images[0], tableItem.getImage(0));
	
	images[0].dispose();
	try {
		tableItem.setImage(0, images[0]);
		tableItem.setImage(0, null);
		fail("No exception thrown for disposed font");
	} catch (IllegalArgumentException e) {
	}
}

public void test_setImageIndentI() {
	if (SwtJunit.isCarbon || SwtJunit.isGTK) {
		//setImageIndent not implemented on Carbon
		tableItem.setImageIndent(1);
		return; 
	}
	assertEquals(0, tableItem.getImageIndent());
 	tableItem.setImageIndent(1);
	assertEquals(1, tableItem.getImageIndent());
 	tableItem.setImageIndent(-1);
	assertEquals(1, tableItem.getImageIndent());
}

public void test_setText$Ljava_lang_String() {
	final String TestString = "test";
	final String TestStrings[] = new String[] {TestString, TestString + "1", TestString + "2"};
	
	try {
		tableItem.setText((String []) null);
		fail("No exception thrown for strings == null");
	}
	catch (IllegalArgumentException e) {
	}
	
   /*
 	* Test the getText/setText API with a Table that has only 
 	* the default column.
 	*/
	
	assertEquals(0, tableItem.getText(1).length());
	
	tableItem.setText(TestStrings);
	assertEquals(TestStrings[0], tableItem.getText(0));
	for (int i = 1; i < TestStrings.length; i++) {
		assertEquals(0, tableItem.getText(i).length());
	}
	
	
   /*
 	* Test the getText/setText API with a Table that enough 
 	* columns to fit all test item texts.
 	*/
 		
	int columnCount = table.getColumnCount();
	if (columnCount < images.length) {
		for (int i = columnCount; i < images.length; i++){
			TableColumn column = new TableColumn(table, SWT.NONE);
		}
	}
	TableColumn[] columns = table.getColumns();
	for (int i = 0; i < TestStrings.length; i++) {
		columns[i].setText(TestStrings[i]);
	}
	assertEquals(0, tableItem.getText(1).length());

}

public void test_setTextILjava_lang_String(){
	final String TestString = "test";
	final String TestStrings[] = new String[] {TestString, TestString + "1", TestString + "2"};

   /*
 	* Test the getText/setText API with a Table that has only 
 	* the default column.
 	*/
	
	assertEquals(0, tableItem.getText(1).length());	
 	tableItem.setText(1, TestString);
	assertEquals(0, tableItem.getText(1).length());	
	assertEquals(0, tableItem.getText(0).length());
	
	tableItem.setText(0, TestString);
	assertEquals(TestString, tableItem.getText(0));
 	tableItem.setText(-1, TestStrings[1]);
	assertEquals(0, tableItem.getText(-1).length());	

   /*
 	* Test the getText/setText API with a Table that enough 
 	* columns to fit all test item texts.
 	*/

	makeCleanEnvironment();
	
	//table.setText(TestStrings);				// create anough columns for TableItem.setText(String[]) to work
	int columnCount = table.getColumnCount();
	if (columnCount < images.length) {
		for (int i = columnCount; i < images.length; i++){
			TableColumn column = new TableColumn(table, SWT.NONE);
		}
	}
	TableColumn[] columns = table.getColumns();
	for (int i = 0; i < TestStrings.length; i++) {
		columns[i].setText(TestStrings[i]);
	}
	assertEquals(0, tableItem.getText(1).length());	


	tableItem.setText(1, TestString);
	assertEquals(TestString, tableItem.getText(1));	
	assertEquals(0, tableItem.getText(0).length());
	
	tableItem.setText(0, TestString);
	assertEquals(TestString, tableItem.getText(0));


	tableItem.setText(-1, TestStrings[1]);
	assertEquals(0, tableItem.getText(-1).length());	


	try {
		tableItem.setText(-1, null);		
		fail("No exception thrown for string == null");
	}
	catch (IllegalArgumentException e) {
	}
	
	try {
		tableItem.setText(0, null);		
		fail("No exception thrown for string == null");
	}
	catch (IllegalArgumentException e) {
	} 


}

public static Test suite() {
	TestSuite suite = new TestSuite();
	java.util.Vector methodNames = methodNames();
	java.util.Enumeration e = methodNames.elements();
	while (e.hasMoreElements()) {
		suite.addTest(new Test_org_eclipse_swt_widgets_TableItem((String)e.nextElement()));
	}
	return suite;
}
public static java.util.Vector methodNames() {
	java.util.Vector methodNames = new java.util.Vector();
	methodNames.addElement("test_ConstructorLorg_eclipse_swt_widgets_TableI");
	methodNames.addElement("test_ConstructorLorg_eclipse_swt_widgets_TableII");
	methodNames.addElement("test_getBackground");
	methodNames.addElement("test_getBackgroundI");
	methodNames.addElement("test_getBoundsI");
	methodNames.addElement("test_getChecked");
	methodNames.addElement("test_getFont");
	methodNames.addElement("test_getFontI");
	methodNames.addElement("test_getForeground");
	methodNames.addElement("test_getForegroundI");
	methodNames.addElement("test_getGrayed");
	methodNames.addElement("test_getImageBoundsI");
	methodNames.addElement("test_getImageI");
	methodNames.addElement("test_getImageIndent");
	methodNames.addElement("test_getParent");
	methodNames.addElement("test_getTextI");
	methodNames.addElement("test_setBackgroundILorg_eclipse_swt_graphics_Color");
	methodNames.addElement("test_setBackgroundLorg_eclipse_swt_graphics_Color");
	methodNames.addElement("test_setCheckedZ");
	methodNames.addElement("test_setFontILorg_eclipse_swt_graphics_Font");
	methodNames.addElement("test_setFontLorg_eclipse_swt_graphics_Font");
	methodNames.addElement("test_setForegroundILorg_eclipse_swt_graphics_Color");
	methodNames.addElement("test_setForegroundLorg_eclipse_swt_graphics_Color");
	methodNames.addElement("test_setGrayedZ");
	methodNames.addElement("test_setImage$Lorg_eclipse_swt_graphics_Image");
	methodNames.addElement("test_setImageILorg_eclipse_swt_graphics_Image");
	methodNames.addElement("test_setImageIndentI");
	methodNames.addElement("test_setImageLorg_eclipse_swt_graphics_Image");
	methodNames.addElement("test_setText$Ljava_lang_String");
	methodNames.addElement("test_setTextILjava_lang_String");
	methodNames.addElement("test_setTextLjava_lang_String");
	methodNames.addAll(Test_org_eclipse_swt_widgets_Item.methodNames()); // add superclass method names
	return methodNames;
}
protected void runTest() throws Throwable {
	if (getName().equals("test_ConstructorLorg_eclipse_swt_widgets_TableI")) test_ConstructorLorg_eclipse_swt_widgets_TableI();
	else if (getName().equals("test_ConstructorLorg_eclipse_swt_widgets_TableII")) test_ConstructorLorg_eclipse_swt_widgets_TableII();
	else if (getName().equals("test_getBackground")) test_getBackground();
	else if (getName().equals("test_getBackgroundI")) test_getBackgroundI();
	else if (getName().equals("test_getBoundsI")) test_getBoundsI();
	else if (getName().equals("test_getChecked")) test_getChecked();
	else if (getName().equals("test_getFont")) test_getFont();
	else if (getName().equals("test_getFontI")) test_getFontI();
	else if (getName().equals("test_getForeground")) test_getForeground();
	else if (getName().equals("test_getForegroundI")) test_getForegroundI();
	else if (getName().equals("test_getGrayed")) test_getGrayed();
	else if (getName().equals("test_getImageBoundsI")) test_getImageBoundsI();
	else if (getName().equals("test_getImageI")) test_getImageI();
	else if (getName().equals("test_getImageIndent")) test_getImageIndent();
	else if (getName().equals("test_getParent")) test_getParent();
	else if (getName().equals("test_getTextI")) test_getTextI();
	else if (getName().equals("test_setBackgroundILorg_eclipse_swt_graphics_Color")) test_setBackgroundILorg_eclipse_swt_graphics_Color();
	else if (getName().equals("test_setBackgroundLorg_eclipse_swt_graphics_Color")) test_setBackgroundLorg_eclipse_swt_graphics_Color();
	else if (getName().equals("test_setCheckedZ")) test_setCheckedZ();
	else if (getName().equals("test_setFontILorg_eclipse_swt_graphics_Font")) test_setFontILorg_eclipse_swt_graphics_Font();
	else if (getName().equals("test_setFontLorg_eclipse_swt_graphics_Font")) test_setFontLorg_eclipse_swt_graphics_Font();
	else if (getName().equals("test_setForegroundILorg_eclipse_swt_graphics_Color")) test_setForegroundILorg_eclipse_swt_graphics_Color();
	else if (getName().equals("test_setForegroundLorg_eclipse_swt_graphics_Color")) test_setForegroundLorg_eclipse_swt_graphics_Color();
	else if (getName().equals("test_setGrayedZ")) test_setGrayedZ();
	else if (getName().equals("test_setImage$Lorg_eclipse_swt_graphics_Image")) test_setImage$Lorg_eclipse_swt_graphics_Image();
	else if (getName().equals("test_setImageILorg_eclipse_swt_graphics_Image")) test_setImageILorg_eclipse_swt_graphics_Image();
	else if (getName().equals("test_setImageIndentI")) test_setImageIndentI();
	else if (getName().equals("test_setImageLorg_eclipse_swt_graphics_Image")) test_setImageLorg_eclipse_swt_graphics_Image();
	else if (getName().equals("test_setText$Ljava_lang_String")) test_setText$Ljava_lang_String();
	else if (getName().equals("test_setTextILjava_lang_String")) test_setTextILjava_lang_String();
	else if (getName().equals("test_setTextLjava_lang_String")) test_setTextLjava_lang_String();
	else super.runTest();
}

/* custom */
Table table;
TableItem tableItem;

// this method must be private or protected so the auto-gen tool keeps it
private void makeCleanEnvironment() {
	if ( tableItem != null ) tableItem.dispose();
	if ( table != null ) table.dispose();
	table = new Table(shell, 0);
	tableItem = new TableItem(table, 0);
	setWidget(tableItem);
}
}
