package org.eclipse.swt.tests.manualJUnit;

import java.text.Collator;
import java.util.Arrays;
import java.util.Locale;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.TextLayout;
import org.eclipse.swt.graphics.TextStyle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

@FixMethodOrder(MethodSorters.JVM)  // To make it easier for human to go through the tests. Same order makes tests easier to recognize.
public class MJ_Table extends MJ_root {

	// Shared elements:
	final Listener ownerDrawnListener = event -> {
		final TableItem item = (TableItem)event.item;
		Table table = item.getParent();
		AtomicBoolean packpending = (AtomicBoolean) table.getData();
		if (event.type == SWT.PaintItem) {
			final String text1 = (String)item.getData();
			if (event.index == 0) {
				event.gc.drawText(text1, event.x, event.y, true);
			}
		}
		if (event.type == SWT.MeasureItem) {
			event.height = 50;
			event.width =  100;
		}
		if (event.type == SWT.SetData) {
			final int index = table.indexOf(item);
			final String data = "Item " + index;
			item.setData(data);
			if (table.getColumnCount() > 1) {
				for (int i = 1; i <= table.getColumnCount(); i++) {
					item.setText(i, "Column: " + i + " " + data);
				}
			}

			// BUG BREAKER.
			if (packpending.get()) {
				packpending.set(false);
				display.asyncExec(() -> {
					table.setRedraw(false);
					for (TableColumn column : table.getColumns()) {
						column.pack();
					}
					table.setRedraw(true);
				});
			}
		}
	};

	@Test
	public void basicTable_Snippet35() {
		Shell shell = mkShell("Basic Table with a few items, no column, no headers");
		shell.setLayout(new FillLayout());
		Table table = new Table (shell, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
		for (int i=0; i<12; i++) {
			TableItem item = new TableItem (table, 0);
			item.setText ("Item " + i);
		}
		shell.setSize (SWIDTH, SHEIGHT);
		shell.open ();
		mainLoop(shell);
	}

	/**
	 *  <a href="https://bugs.eclipse.org/bugs/attachment.cgi?id=272647">Screenshot </a>
	 */
	@Test
	public void ownerDrawn_cheese_single_column () {
		Shell shell = mkShell("Expected: There should be no cheese in the items. Move over shouldn't cheese out. See javadoc for screenshot");
		shell.setLayout(new FillLayout(SWT.VERTICAL));

		final Table table = new Table(shell, SWT.VIRTUAL | SWT.BORDER |  SWT.H_SCROLL | SWT.V_SCROLL);

		AtomicBoolean packpending = new AtomicBoolean(true);
		table.setData(packpending);

		table.addListener(SWT.EraseItem, ownerDrawnListener);
		table.addListener(SWT.SetData, ownerDrawnListener);
		table.addListener(SWT.MeasureItem, ownerDrawnListener);
		table.addListener(SWT.PaintItem, ownerDrawnListener);

		final TableColumn tableColumn = new TableColumn(table, SWT.LEFT);
		tableColumn.setText("First Left Column");
		tableColumn.setMoveable(true);


		for (int i = 0; i < 100; i++) {
			TableItem item1 = new TableItem(table, SWT.NONE);
			item1.setText("hello " + i);
		}

//		for (int i = 0; i < 2; i++) {
//			table.getColumn(i).setWidth(1);							// Setting width seems to fix issue.
//			table.getColumn(i).pack(); // table is empty on Gtk3.	// packing doesn't fix issue.
//		}

		shell.setSize(800, 600); // Shell size seems to have a litlte bit of an initial impact. (may show proper with some shell sizes, incorrectly for others).
		shell.open();
		mainLoop(shell);
	}

	@Test
	public void ownerDrawn_cheese_multiple_columns() {
		final Shell shell = mkShell("Expected: No cheese in multiple column, also mouse move over no cheese.");
		shell.setLayout(new FillLayout(SWT.VERTICAL));
		final Table table = new Table(shell, SWT.VIRTUAL | SWT.BORDER |  SWT.H_SCROLL | SWT.V_SCROLL);

		AtomicBoolean packpending = new AtomicBoolean(true);
		table.setData(packpending);

		table.addListener(SWT.EraseItem, ownerDrawnListener);
		table.addListener(SWT.SetData, ownerDrawnListener);
		table.addListener(SWT.MeasureItem, ownerDrawnListener);
		table.addListener(SWT.PaintItem, ownerDrawnListener);

		BiConsumer<Integer, String> createColCons = (colStyle, colName) -> {
			final TableColumn tableColumn = new TableColumn(table, colStyle);
			tableColumn.setText(colName);
			tableColumn.setMoveable(true);
		};

		createColCons.accept(SWT.LEFT, "LEFT");
		createColCons.accept(SWT.CENTER, "CENTER");
		createColCons.accept(SWT.RIGHT, "RIGHT");

		int ItemCount = 1000;
		table.setItemCount(ItemCount);
		table.setHeaderVisible(true);

		shell.setSize(SWIDTH, SHEIGHT);
		shell.open();
		mainLoop(shell);
	}


	/**
	 * <a href="http://www.eclipse.org/articles/Article-CustomDrawingTableAndTreeItems/customDraw.htm#_example4"> Screenshot </a>
	 */
	@Test
	public void ownerDrawn_eraseItem_Snippet273() {
		knownToBeBrokenGtk3("Test currently broken on Gtk3. See Comment#1 of Bug 531551");

		final String[] MONTHS = {
				"Jan", "Feb", "Mar", "Apr", "May", "Jun",
				"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
			};
		final int[] HIGHS = {-7, -4, 1, 11, 18, 24, 26, 25, 20, 13, 5, -4};
		final int[] LOWS = {-15, -13, -7, 1, 7, 13, 15, 14, 10, 4, -2, -11};
		final int SCALE_MIN = -30; final int SCALE_MAX = 30;
		final int SCALE_RANGE = Math.abs(SCALE_MIN - SCALE_MAX);

		Shell shell = mkShell(" Gtk3:broken, no erasing (1st March 2018)   Gtk2: Background is used as bar-chart of sort. See screenshot.");
		final Color blue = display.getSystemColor(SWT.COLOR_BLUE);
		final Color white = display.getSystemColor(SWT.COLOR_WHITE);
		final Color red = display.getSystemColor(SWT.COLOR_RED);
//			 final Image parliamentImage = new Image(display, "./parliament.jpg");
		final Table table = new Table(shell, SWT.NONE);
		table.setBounds(10,10,350,300);
//			 table.setBackgroundImage(parliamentImage);
		for (int i = 0; i < 12; i++) {
			TableItem item = new TableItem(table, SWT.NONE);
			item.setText(MONTHS[i] + " (" + LOWS[i] + "C..." + HIGHS[i] + "C)");
		}
		final int clientWidth = table.getClientArea().width;

		/*
		 * NOTE: MeasureItem and EraseItem are called repeatedly. Therefore it is
		 * critical for performance that these methods be as efficient as possible.
		 */
		table.addListener(SWT.MeasureItem, event -> {
			int itemIndex = table.indexOf((TableItem)event.item);
			int rightX = (HIGHS[itemIndex] - SCALE_MIN) * clientWidth / SCALE_RANGE;
			event.width = rightX;
		});
		table.addListener(SWT.EraseItem, event -> {
			int itemIndex = table.indexOf((TableItem)event.item);
			int leftX = (LOWS[itemIndex] - SCALE_MIN) * clientWidth / SCALE_RANGE;
			int rightX = (HIGHS[itemIndex] - SCALE_MIN) * clientWidth / SCALE_RANGE;
			GC gc = event.gc;
			Rectangle clipping = gc.getClipping();
			clipping.x = leftX;
			clipping.width = rightX - leftX;
			gc.setClipping(clipping);
			Color oldForeground = gc.getForeground();
			Color oldBackground = gc.getBackground();
			gc.setForeground(blue);
			gc.setBackground(white);
			gc.fillGradientRectangle(event.x, event.y, event.width / 2, event.height, false);
			gc.setForeground(white);
			gc.setBackground(red);
			gc.fillGradientRectangle(
				event.x + event.width / 2, event.y, event.width / 2, event.height, false);
			gc.setForeground(oldForeground);
			gc.setBackground(oldBackground);
			event.detail &= ~SWT.BACKGROUND;
			event.detail &= ~SWT.HOT;
		});
		shell.setSize(SWIDTH, SHEIGHT);
		shell.open();
		mainLoop(shell);
	}

	@Test
	public void ownerDrawn_icons_on_right_side_of_column_Snippet230() {
		Shell shell = mkShell("Verify icons are visible on all columns on right side. (on gtk3, icons are cut off Bug 531882)");
		knownToBeBrokenGtk3("On gtk3, icons in col 1 and 2 are cut off. Bug 531882");

		final Image image = display.getSystemImage(SWT.ICON_INFORMATION);
		shell.setLayout(new FillLayout ());
		Table table = new Table(shell, SWT.MULTI | SWT.FULL_SELECTION);
		table.setHeaderVisible(true);
		table.setLinesVisible(true);
		int columnCount = 3;
		for (int i=0; i<columnCount; i++) {
			TableColumn column = new TableColumn(table, SWT.NONE);
			column.setText("Column " + i);
		}
		int itemCount = 8;
		for(int i = 0; i < itemCount; i++) {
			TableItem item = new TableItem(table, SWT.NONE);
			item.setText(new String[] {"item "+i+" a", "item "+i+" b", "item "+i+" c"});
		}

		/*
		 * NOTE: MeasureItem, PaintItem and EraseItem are called repeatedly.
		 * Therefore, it is critical for performance that these methods be
		 * as efficient as possible.
		 */
		Listener paintListener = event -> {
			switch(event.type) {
				case SWT.MeasureItem: {
					Rectangle rect1 = image.getBounds();
					event.width += rect1.width;
					event.height = Math.max(event.height, rect1.height + 2);
					break;
				}
				case SWT.PaintItem: {
					int x = event.x + event.width;
					Rectangle rect2 = image.getBounds();
					int offset = Math.max(0, (event.height - rect2.height) / 2);
					event.gc.drawImage(image, x, event.y + offset);
					break;
				}
			}
		};
		table.addListener(SWT.MeasureItem, paintListener);
		table.addListener(SWT.PaintItem, paintListener);

		for(int i = 0; i < columnCount; i++) {
			table.getColumn(i).pack();
		}
		shell.setSize (SWIDTH, SHEIGHT);
		shell.open();
		shell.addDisposeListener(e -> {
			if(image != null) image.dispose();
		});
		mainLoop(shell);
	}

	@Test
	public void ownerDrawn_barChart_Snippet228() {
		Shell shell = mkShell("Ensure you see bar-charts in 2nd column and they resize with shell.");
		shell.setLayout(new FillLayout());
		final Table table = new Table(shell, SWT.BORDER);
		table.setHeaderVisible(true);
		table.setLinesVisible(true);
		TableColumn column1 = new TableColumn(table, SWT.NONE);
		column1.setText("Bug Status");
		column1.setWidth(100);
		final TableColumn column2 = new TableColumn(table, SWT.NONE);
		column2.setText("Percent");
		column2.setWidth(200);
		String[] labels = new String[]{"Resolved", "New", "Won't Fix", "Invalid"};
		for (int i=0; i<labels.length; i++) {
			 TableItem item = new TableItem(table, SWT.NONE);
			 item.setText(labels[i]);
		}

		/*
		 * NOTE: MeasureItem, PaintItem and EraseItem are called repeatedly.
		 * Therefore, it is critical for performance that these methods be
		 * as efficient as possible.
		 */
		table.addListener(SWT.PaintItem, new Listener() {
			int[] percents = new int[] {50, 30, 5, 15};
			@Override
			public void handleEvent(Event event) {
				if (event.index == 1) {
					GC gc = event.gc;
					TableItem item = (TableItem)event.item;
					int index = table.indexOf(item);
					int percent = percents[index];
					Color foreground = gc.getForeground();
					Color background = gc.getBackground();
					gc.setForeground(display.getSystemColor(SWT.COLOR_RED));
					gc.setBackground(display.getSystemColor(SWT.COLOR_YELLOW));
					int width = (column2.getWidth() - 1) * percent / 100;
					gc.fillGradientRectangle(event.x, event.y, width, event.height, true);
					Rectangle rect2 = new Rectangle(event.x, event.y, width-1, event.height-1);
					gc.drawRectangle(rect2);
					gc.setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
					String text = percent+"%";
					Point size = event.gc.textExtent(text);
					int offset = Math.max(0, (event.height - size.y) / 2);
					gc.drawText(text, event.x+2, event.y+offset, true);
					gc.setForeground(background);
					gc.setBackground(foreground);
				}
			}
		});
		shell.setSize (SWIDTH, SHEIGHT);
		shell.open();
		mainLoop(shell);
	}

	@Test
	public void ownerDrawn_textAlignment_Snippet231 () {
		Shell shell = mkShell("Ensure there is no cheese, also when hoving over items");
		final int COLUMN_COUNT = 4;
		final int ITEM_COUNT = 8;
		final int TEXT_MARGIN = 3;
		shell.setLayout(new FillLayout());
		final Table table = new Table(shell, SWT.FULL_SELECTION);
		table.setHeaderVisible(true);
		table.setLinesVisible(true);
		for (int i = 0; i < COLUMN_COUNT; i++) {
			new TableColumn(table, SWT.NONE);
		}
		for (int i = 0; i < ITEM_COUNT; i++) {
			TableItem item = new TableItem(table, SWT.NONE);
			for (int j = 0; j < COLUMN_COUNT; j++) {
				String string = "item " + i + " col " + j;
				if ((i + j) % 3 == 1) {
					string +="\nnew line1";
				}
				if ((i + j) % 3 == 2) {
					string +="\nnew line1\nnew line2";
				}
				item.setText(j, string);
			}
		}

		/*
		 * NOTE: MeasureItem, PaintItem and EraseItem are called repeatedly.
		 * Therefore, it is critical for performance that these methods be
		 * as efficient as possible.
		 */
		table.addListener(SWT.MeasureItem, event -> {
			TableItem item = (TableItem)event.item;
			String text = item.getText(event.index);
			Point size = event.gc.textExtent(text);
			event.width = size.x + 2 * TEXT_MARGIN;
			event.height = Math.max(event.height, size.y + TEXT_MARGIN);
		});
		table.addListener(SWT.EraseItem, event -> event.detail &= ~SWT.FOREGROUND);
		table.addListener(SWT.PaintItem, event -> {
			TableItem item = (TableItem)event.item;
			String text = item.getText(event.index);
			/* center column 1 vertically */
			int yOffset = 0;
			if (event.index == 1) {
				Point size = event.gc.textExtent(text);
				yOffset = Math.max(0, (event.height - size.y) / 2);
			}
			event.gc.drawText(text, event.x + TEXT_MARGIN, event.y + yOffset, true);
		});

		for (int i = 0; i < COLUMN_COUNT; i++) {
			table.getColumn(i).pack();
		}
		shell.open();
		mainLoop(shell);
	}

	@Test
	public void ownerDrawn_multiColumn_gc_snippet239 () {
		Shell shell = mkShell("Verify that text is correctly drawn across 2 columns");
		shell.setText("Text spans two columns in a TableItem");
		shell.setLayout (new FillLayout());
		final Table table = new Table(shell, SWT.MULTI | SWT.FULL_SELECTION);
		table.setHeaderVisible(true);
		int columnCount = 4;
		for (int i=0; i<columnCount; i++) {
			TableColumn column = new TableColumn(table, SWT.NONE);
			column.setText("Column " + i);
		}
		int itemCount = 8;
		for (int i = 0; i < itemCount; i++) {
			TableItem item = new TableItem(table, SWT.NONE);
			item.setText(0, "item "+i+" a");
			item.setText(3, "item "+i+" d");
		}
		/*
		 * NOTE: MeasureItem, PaintItem and EraseItem are called repeatedly.
		 * Therefore, it is critical for performance that these methods be
		 * as efficient as possible.
		 */
		final String string = "text that spans two columns";
		GC gc = new GC(table);
		final Point extent = gc.stringExtent(string);
		gc.dispose();
		final Color red = display.getSystemColor(SWT.COLOR_RED);
		Listener paintListener = event -> {
			switch(event.type) {
				case SWT.MeasureItem: {
					if (event.index == 1 || event.index == 2) {
						event.width = extent.x/2;
						event.height = Math.max(event.height, extent.y + 2);
					}
					break;
				}
				case SWT.PaintItem: {
					if (event.index == 1 || event.index == 2) {
						int offset = 0;
						if (event.index == 2) {
							TableColumn column1 = table.getColumn(1);
							offset = column1.getWidth();
						}
						event.gc.setForeground(red);
						int y = event.y + (event.height - extent.y)/2;
						event.gc.drawString(string, event.x - offset, y, true);
					}
					break;
				}
			}
		};
		table.addListener(SWT.MeasureItem, paintListener);
		table.addListener(SWT.PaintItem, paintListener);
		for (int i = 0; i < columnCount; i++) {
			table.getColumn(i).pack();
		}
		shell.setSize(SWIDTH, SHEIGHT);
		shell.open();
		mainLoop(shell);
	}

	@Test
	public void ownerDrawn_CustomItemHeight () {
		Shell shell = mkShell("Ensure Item 3 (yellow) is bigger than the other items");
		int bigItem = 3;

		shell.setLayout(new FillLayout());
		shell.setSize (SWIDTH, SHEIGHT);
		final Table table = new Table(shell, SWT.NONE);
		table.setLinesVisible(true);


		for (int i = 0; i < 5; i++) {
			TableItem item = new TableItem(table, SWT.NONE);
			if (i == bigItem) {
				item.setText("Item " + bigItem + " has bigger height");
				item.setBackground(display.getSystemColor(SWT.COLOR_YELLOW));
			}
			else {
				item.setText("item " + i);
				item.setBackground(display.getSystemColor(SWT.COLOR_DARK_GRAY));
			}
		}

		/*
		 * NOTE: MeasureItem is called repeatedly.  Therefore it is critical
		 * for performance that this method be as efficient as possible.
		 */
		table.addListener(SWT.MeasureItem, event -> {
			int clientWidth = table.getClientArea().width;
			event.height = event.gc.getFontMetrics().getHeight() * 2; // * table.indexOf((TableItem) event.item)  to have different height rows.
			event.width = clientWidth * 2;

			if (table.indexOf((TableItem) event.item) == bigItem) {
				event.height *= 2;
			}
		});

		shell.open();
		mainLoop(shell);
	}


	/**
	 * Snippet 144 modified to auto-populate items when shell is activated instead.
	 */
	@Test
	public void virtual_addManyItems_Snippet144 () {
		final Shell shell = mkShell("Shell Should show and items should be populated in lazy way");
		shell.setSize (SWIDTH, SHEIGHT);
		final int COUNT = 100000;
		shell.setLayout(new RowLayout(SWT.VERTICAL));
		final Table table = new Table (shell, SWT.VIRTUAL | SWT.BORDER);
		final Label label1 = new Label(shell, SWT.NONE);
		table.addListener (SWT.SetData, event -> {
			TableItem item = (TableItem) event.item;
			int index = table.indexOf (item);
			item.setText ("Item  " + index);
			label1.setText("Added " + item.getText());
		});
		table.setLayoutData (new RowData (shell.getBounds().width - 100, 400));
		final Label label2 = new Label(shell, SWT.NONE);
		shell.addShellListener( new ShellAdapter() {
			@Override
			public void shellActivated(ShellEvent e) {
				System.out.println("activated");
				long t1 = System.currentTimeMillis ();
				table.setItemCount (COUNT);
				long t2 = System.currentTimeMillis ();
				label2.setText ("Items: " + COUNT + ", Time: " + (t2 - t1) + " (ms)");
				shell.layout ();
			}
		});
		shell.open ();
		mainLoop(shell);
	}

	@Test
	public void column_headers_Snippet38() {
		Shell shell = mkShell("Matrix with rows & columns and columns with description. (BUG gtk2/3 text seems slightly cut off, Bug 531875)");
		knownToBeBrokenGtk("Text in column is cut off at the moment. See Bug 531875");

		shell.setLayout(new GridLayout());
		Table table = new Table (shell, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION);
		table.setLinesVisible (true);
		table.setHeaderVisible (true);
		GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
		data.heightHint = 200;
		table.setLayoutData(data);
		String[] titles = {" ", "C", "!", "Description", "Resource", "In Folder", "Location"};
		for (int i=0; i<titles.length; i++) {
			TableColumn column = new TableColumn (table, SWT.NONE);
			column.setText (titles [i]);
		}
		int count = 128;
		for (int i=0; i<count; i++) {
			TableItem item = new TableItem (table, SWT.NONE);
			item.setText (0, "x");
			item.setText (1, "y");
			item.setText (2, "!");
			item.setText (3, "this stuff behaves the way I expect");
			item.setText (4, "almost everywhere");
			item.setText (5, "some.folder");
			item.setText (6, "line " + i + " in nowhere");
		}
		for (int i=0; i<titles.length; i++) {
			table.getColumn (i).pack ();
		}
		shell.setSize(SWIDTH, SHEIGHT);
		shell.open ();
		mainLoop(shell);
	}


	// TODO - see how this behaves on windows.
	@Test
	public void column_noWidth_bug399522 () {
		Shell shell = mkShell("Expected : (Not sure?) On Gtk/Cocoa no items are now shown till column width is actually specified or column is packed.");

		final Table table = new Table(shell, SWT.BORDER);
		table.setHeaderVisible(true);

		new TableItem(table, SWT.NONE).setText("Item1");
		TableColumn column1 = new TableColumn(table, SWT.NONE);
//		column1.setWidth(10);	// Setting column width makes items visible.
//		column1.pack();

		table.setSize(200, 200);
		System.out.println(column1.handle);

		shell.addListener(SWT.MouseDown, event -> System.out.println(table.computeSize(-1, -1)));

		TableColumn col2 = new TableColumn(table, SWT.NONE);
		System.out.println(col2.handle);

		shell.setSize(SWIDTH, SHEIGHT);
		shell.open();
		mainLoop(shell);
	}


	@Test
	public void column_header_icons_Snippet297() {
		Display display = new Display ();
		Image images[] = new Image[] {
			display.getSystemImage(SWT.ICON_INFORMATION),
			display.getSystemImage(SWT.ICON_ERROR),
			display.getSystemImage(SWT.ICON_QUESTION),
			display.getSystemImage(SWT.ICON_WARNING),
		};
		String[] titles = {"Information", "Error", "Question", "Warning"};
		String[] questions = {"who?", "what?", "where?", "when?", "why?"};
		Shell shell = new Shell (display);
		shell.setLayout(new GridLayout());
		Table table = new Table (shell, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION);
		GridData data = new GridData (SWT.FILL, SWT.FILL, true, true);
		data.heightHint = 200;
		table.setLayoutData (data);
		table.setLinesVisible (true);
		table.setHeaderVisible (true);

		for (int i=0; i<titles.length; i++) {
			TableColumn column = new TableColumn (table, SWT.NONE);
			column.setText (titles [i]);
			column.setImage(images [i]);
		}

		int count = 128;
		for (int i=0; i<count; i++) {
			TableItem item = new TableItem (table, SWT.NONE);
			item.setText (0, "some info");
			item.setText (1, "error #" + i);
			item.setText (2, questions [i % questions.length]);
			item.setText (3, "look out!");
		}
		for (int i=0; i<titles.length; i++) {
			table.getColumn (i).pack ();
		}

		table.setHeaderBackground(display.getSystemColor(SWT.COLOR_BLUE));
		table.setHeaderForeground(display.getSystemColor(SWT.COLOR_RED));

		shell.setSize(SWIDTH, SHEIGHT);
		shell.open ();
		mainLoop(shell);
	}

	/**
	 * Based on Snippet 106 with some modificaitons.
	 */
	@Test
	public void column_dynamically_added_after_shellOpened_Snippet106() {
		Shell shell = mkShell("Verify dynamic column (2) was added properly.");

		final Table table = new Table (shell, SWT.BORDER | SWT.MULTI);
		table.setHeaderVisible (true);
		for (int i=0; i<4; i++) {
			TableColumn column = new TableColumn (table, SWT.NONE);
			column.setText ("Column " + i);
		}
		final TableColumn [] columns = table.getColumns ();
		for (int i=0; i<12; i++) {
			TableItem item = new TableItem (table, SWT.NONE);
			for (int j=0; j<columns.length; j++) {
				item.setText (j, "Item " + i);
			}
		}
		for (int i=0; i<columns.length; i++) columns [i].pack ();
		Button button = new Button (shell, SWT.PUSH);
		final int index = 1;
		button.setText ("Insert Column " + index + "a");
		shell.addShellListener(new ShellAdapter() {
			@Override
			public void shellActivated(ShellEvent e) {
				TableColumn column = new TableColumn (table, SWT.NONE, index);
				column.setImage(display.getSystemImage(SWT.ICON_WARNING)); //added to make it easier to spot in a test.
				column.setText ("Column " + index + " added after shellopen");
				TableItem [] items = table.getItems ();
				for (int i=0; i<items.length; i++) {
					items [i].setText (index, "Item " + i + " added");
				}
				column.pack ();
			}
		});

		shell.setSize (SWIDTH, SHEIGHT);
		Rectangle shellClientArea = shell.getClientArea();
		table.setSize(shellClientArea.width, shellClientArea.height);
		shell.open ();
		mainLoop(shell);
	}

	@Test
	public void column_dynamic_resize() {
		Shell shell = mkShell("Try resizing shell. Columns should resize as you resize shell");
		shell.setLayout(new FillLayout());

		final Composite comp = new Composite(shell, SWT.NONE);
		final Table table = new Table(comp, SWT.BORDER | SWT.V_SCROLL);
		table.setHeaderVisible(true);
		table.setLinesVisible(true);
		final TableColumn column1 = new TableColumn(table, SWT.NONE);
		column1.setText("Column 1");
		final TableColumn column2 = new TableColumn(table, SWT.NONE);
		column2.setText("Column 2");
		for (int i = 0; i < 10; i++) {
			TableItem item = new TableItem(table, SWT.NONE);
			item.setText(new String[] {"item 0" + i, "item 1"+i});
		}
		comp.addControlListener(ControlListener.controlResizedAdapter(e -> {
			Rectangle area = comp.getClientArea();
			Point size = table.computeSize(SWT.DEFAULT, SWT.DEFAULT);
			ScrollBar vBar = table.getVerticalBar();
			int width = area.width - table.computeTrim(0, 0, 0, 0).width - vBar.getSize().x;
			if (size.y > area.height + table.getHeaderHeight()) {
				// Subtract the scrollbar width from the total column width
				// if a vertical scrollbar will be required
				Point vBarSize = vBar.getSize();
				width -= vBarSize.x;
			}
			Point oldSize = table.getSize();
			if (oldSize.x > area.width) {
				// table is getting smaller so make the columns
				// smaller first and then resize the table to
				// match the client area width
				column1.setWidth(width / 3);
				column2.setWidth(width - column1.getWidth());
				table.setSize(area.width, area.height);
			} else {
				// table is getting bigger so make the table
				// bigger first and then make the columns wider
				// to match the client area width
				table.setSize(area.width, area.height);
				column1.setWidth(width / 3);
				column2.setWidth(width - column1.getWidth());
			}
		}));

		shell.open();
		mainLoop(shell);
	}

	@Test
	public void measureItem_custom_Column_width_onPack_Snippet272() {
		Shell shell = mkShell("Double click on column boundary '|', observe column get's bigger");
		shell.setSize(SWIDTH, SHEIGHT);
		shell.setLayout(new FillLayout());
		Table table = new Table(shell, SWT.NONE);
		table.setHeaderVisible(true);
		table.setLinesVisible(true);
		final TableColumn column0 = new TableColumn(table, SWT.NONE);
		column0.setWidth(110);
		column0.setText("2x Click pipe ->");
		final TableColumn column1 = new TableColumn(table, SWT.NONE);
		column1.setWidth(110);
		column0.addListener(SWT.Selection, event -> column0.pack());
		column1.addListener(SWT.Selection, event -> column1.pack());
		for (int i = 0; i < 5; i++) {
			TableItem item = new TableItem(table, SWT.NONE);
			item.setText(0, "item " + i + " col 0");
			item.setText(1, "item " + i + " col 1");
		}

		/*
		 * NOTE: MeasureItem is called repeatedly.  Therefore it is critical
		 * for performance that this method be as efficient as possible.
		 */
		table.addListener(SWT.MeasureItem, event -> event.width *= 4);  // This guy makes the difference.

		shell.open();
		mainLoop(shell);
	}

	@Test
	public void checkBoxes() {
		Shell shell = mkShell("You should see some checkboxes");
		shell.setLayout(new FillLayout());
		Table table = new Table (shell, SWT.CHECK | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
		for (int i=0; i<12; i++) {
			TableItem item = new TableItem (table, SWT.NONE);
			item.setText ("Item " + i);
		}
		Rectangle clientArea = shell.getClientArea ();
		table.setBounds (clientArea.x, clientArea.y, 600, 500);

		final Label label = new Label(shell, SWT.NONE);

		table.addListener (SWT.Selection, event -> {
			String string = event.detail == SWT.CHECK ? "Checked" : "Selected";
			label.setText(event.item + " " + string);
		});
		shell.setSize(SWIDTH, SHEIGHT);
		shell.open ();
		mainLoop(shell);
	}

	@Test
	public void color_singleColumn() {
		Shell shell = mkShell("Header and content should be colored red and blue. Column header should be of a darker color.");
		shell.setLayout(new FillLayout());

		Table table = new Table (shell, SWT.None);
		table.setHeaderVisible(true);
		TableColumn column = new TableColumn(table, SWT.LEFT);
		column.setText("Column header has darker colors.");
		column.pack();

		for (int i = 0; i < 200; i++) {
			TableItem item = new TableItem(table, SWT.None);
			item.setText("Item " + i);
		}

		table.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
		table.setForeground(display.getSystemColor(SWT.COLOR_RED));

		table.setHeaderBackground(display.getSystemColor(SWT.COLOR_DARK_BLUE));
		table.setHeaderForeground(display.getSystemColor(SWT.COLOR_DARK_RED));

		shell.open();
		mainLoop(shell);
	}

	@Test
	public void color_MultipleColumn() {
		Shell shell = mkShell("Header and content should be colored red and blue. Column header should be of a darker color.");
		shell.setLayout(new FillLayout());

		Table table = new Table (shell, SWT.None);
		table.setHeaderVisible(true);
		TableColumn column = new TableColumn(table, SWT.LEFT);
		column.setText("Column 1");
		column.pack();

		TableColumn column2 = new TableColumn(table, SWT.LEFT);
		column2.setText("Column 2");
		column2.pack();

		for (int i = 0; i < 200; i++) {
			TableItem item = new TableItem(table, SWT.None);
			item.setText(new String[] {"Item " + i,  "Item col2: " + i});
		}

		table.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
		table.setForeground(display.getSystemColor(SWT.COLOR_RED));

		table.setHeaderBackground(display.getSystemColor(SWT.COLOR_DARK_BLUE));
		table.setHeaderForeground(display.getSystemColor(SWT.COLOR_DARK_RED));

		shell.open();
		mainLoop(shell);
	}

	@Test
	public void color_differentCells_Snippet129 () {
		Shell shell = mkShell("Table cells should be of different colors");

		Color red = display.getSystemColor(SWT.COLOR_RED);
		Color blue = display.getSystemColor(SWT.COLOR_BLUE);
		Color white = display.getSystemColor(SWT.COLOR_WHITE);
		Color gray = display.getSystemColor(SWT.COLOR_GRAY);
		shell.setLayout(new FillLayout());
		Table table = new Table(shell, SWT.BORDER | SWT.FULL_SELECTION);
		table.setBackground(gray);
		TableColumn column1 = new TableColumn(table, SWT.NONE);
		TableColumn column2 = new TableColumn(table, SWT.NONE);
		TableColumn column3 = new TableColumn(table, SWT.NONE);
		TableItem item = new TableItem(table, SWT.NONE);
		item.setText(new String[] {"entire","row","red foreground"});
		item.setForeground(red);
		item = new TableItem(table, SWT.NONE);
		item.setText(new String[] {"entire","row","red background"});
		item.setBackground(red);
		item = new TableItem(table, SWT.NONE);
		item.setText(new String[] {"entire","row","white fore/red back"});
		item.setForeground(white);
		item.setBackground(red);
		item = new TableItem(table, SWT.NONE);
		item.setText(new String[] {"normal","blue foreground","red foreground"});
		item.setForeground(1, blue);
		item.setForeground(2, red);
		item = new TableItem(table, SWT.NONE);
		item.setText(new String[] {"normal","blue background","red background"});
		item.setBackground(1, blue);
		item.setBackground(2, red);
		item = new TableItem(table, SWT.NONE);
		item.setText(new String[] {"white fore/blue back","normal","white fore/red back"});
		item.setForeground(0, white);
		item.setBackground(0, blue);
		item.setForeground(2, white);
		item.setBackground(2, red);

		column1.pack();
		column2.pack();
		column3.pack();

		shell.setSize(SWIDTH, SHEIGHT);
		shell.open();
		mainLoop(shell);
	}

	@Test
	public void programaticScrolling_Snippet52() {
		Shell shell = mkShell("Table should be scrolled down to 100th item");
		Table table = new Table (shell, SWT.BORDER | SWT.MULTI);
		Rectangle clientArea = shell.getClientArea ();
		table.setBounds (clientArea.x, clientArea.y,800, 600);
		for (int i=0; i<128; i++) {
			TableItem item = new TableItem (table, SWT.NONE);
			item.setText ("Item " + i);
		}
		table.setSelection (100);					// <<< This is what we're testing.
		shell.pack ();
		shell.open ();
		mainLoop(shell);
	}

	@Test
	public void sort_by_column_Snippet2() {
	    Shell shell = mkShell("Click on columns to verify items are sorted properly");
	    shell.setLayout(new FillLayout());

	    final Table table = new Table(shell, SWT.BORDER);
	    table.setHeaderVisible(true);
	    final TableColumn column1 = new TableColumn(table, SWT.NONE);
	    column1.setText("Column 1");
	    final TableColumn column2 = new TableColumn(table, SWT.NONE);
	    column2.setText("Column 2");
	    TableItem item = new TableItem(table, SWT.NONE);
	    item.setText(new String[] {"a", "3"});
	    item = new TableItem(table, SWT.NONE);
	    item.setText(new String[] {"b", "2"});
	    item = new TableItem(table, SWT.NONE);
	    item.setText(new String[] {"c", "1"});
	    column1.setWidth(100);
	    column2.setWidth(100);
	    Listener sortListener = e -> {
		    TableItem[] items = table.getItems();
		    Collator collator = Collator.getInstance(Locale.getDefault());
		    TableColumn column = (TableColumn)e.widget;
		    int index = column == column1 ? 0 : 1;
		    for (int i = 1; i < items.length; i++) {
		        String value1 = items[i].getText(index);
		        for (int j = 0; j < i; j++){
		            String value2 = items[j].getText(index);
		            if (collator.compare(value1, value2) < 0) {
		                String[] values = {items[i].getText(0), items[i].getText(1)};
		                items[i].dispose();
		                TableItem item1 = new TableItem(table, SWT.NONE, j);
		                item1.setText(values);
		                items = table.getItems();
		                break;
		            }
		        }
		    }
		    table.setSortColumn(column);
		};
	    column1.addListener(SWT.Selection, sortListener);
	    column2.addListener(SWT.Selection, sortListener);
	    table.setSortColumn(column1);
	    table.setSortDirection(SWT.UP);
	    shell.setSize(SWIDTH, SHEIGHT);
	    shell.open();
	    mainLoop(shell);
	}

	@Test
	public void sort_by_columnt_virtual_Snippet192 () {
		Shell shell = mkShell("Click on column heading to sort");
		// initialize data with keys and random values
		int size = 100;
		Random random = new Random();
		final int[][] data = new int[size][];
		for (int i = 0; i < data.length; i++) {
			data[i] = new int[] {i, random.nextInt()};
		}
		// create a virtual table to display data
		shell.setLayout(new FillLayout());
		final Table table = new Table(shell, SWT.VIRTUAL);
		table.setHeaderVisible(true);
		table.setLinesVisible(true);
		table.setItemCount(size);
		final TableColumn column1 = new TableColumn(table, SWT.NONE);
		column1.setText("Key");
		column1.setWidth(200);
		final TableColumn column2 = new TableColumn(table, SWT.NONE);
		column2.setText("Value");
		column2.setWidth(200);
		table.addListener(SWT.SetData, e -> {
			TableItem item = (TableItem) e.item;
			int index = table.indexOf(item);
			int[] datum = data[index];
			item.setText(new String[] {Integer.toString(datum[0]),
					Integer.toString(datum[1]) });
		});
		// Add sort indicator and sort data when column selected
		Listener sortListener = e -> {
			// determine new sort column and direction
			TableColumn sortColumn = table.getSortColumn();
			TableColumn currentColumn = (TableColumn) e.widget;
			int dir = table.getSortDirection();
			if (sortColumn == currentColumn) {
				dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
			} else {
				table.setSortColumn(currentColumn);
				dir = SWT.UP;
			}
			// sort the data based on column and direction
			final int index = currentColumn == column1 ? 0 : 1;
			final int direction = dir;
			Arrays.sort(data, (a, b) -> {
				if (a[index] == b[index]) return 0;
				if (direction == SWT.UP) {
					return a[index] < b[index] ? -1 : 1;
				}
				return a[index] < b[index] ? 1 : -1;
			});
			// update data displayed in table
			table.setSortDirection(dir);
			table.clearAll();
		};
		column1.addListener(SWT.Selection, sortListener);
		column2.addListener(SWT.Selection, sortListener);
		table.setSortColumn(column1);
		table.setSortDirection(SWT.UP);
		shell.setSize(SWIDTH, SHEIGHT);
		shell.open();
		mainLoop(shell);
	}

	@Test
	public void icons_ofDiffSize_inItems_Snippet349() {
		Shell shell = mkShell("Verify that items have icons of different sizes and icons are not cut off");

		BiFunction<Integer, Integer, Image> createImage = (width, height) -> {
			Image result = new Image(display, width, height);
			GC gc = new GC(result);
			for (int x = -height; x < width; x += 4) {
				gc.drawLine(x, 0, x + height, height);
			}
			gc.dispose();
			return result;
		};

		final int COLUMN_COUNT = 3;
		final int TEXT_MARGIN = 3;
		final String KEY_WIDTHS = "widths";
		final String KEY_IMAGES = "images";

		Image[] images = new Image[4];
		images[0] = createImage.apply(16, 16);
		images[1] = createImage.apply(32, 16);
		images[2] = createImage.apply(48, 16);

		shell.setLayout(new FillLayout());
		Table table = new Table(shell, SWT.NONE);
		for (int i = 0; i < COLUMN_COUNT; i++) {
			new TableColumn(table, SWT.NONE);
		}
		for (int i = 0; i < 8; i++) {
			TableItem item = new TableItem(table, SWT.NONE);
			Image[] itemImages = new Image[COLUMN_COUNT];
			item.setData(KEY_IMAGES, itemImages);
			for (int j = 0; j < COLUMN_COUNT; j++) {
				item.setText(j, "item " + i + " col " + j);
				itemImages[j] = images[(i * COLUMN_COUNT + j) % images.length];
			}
		}

		/*
		 * NOTE: MeasureItem, PaintItem and EraseItem are called repeatedly.
		 * Therefore, it is critical for performance that these methods be
		 * as efficient as possible.
		 */
		final int itemHeight = table.getItemHeight();
		GC gc = new GC(table);
		FontMetrics metrics = gc.getFontMetrics();
		final int fontHeight = metrics.getHeight();
		gc.dispose();
		Listener paintListener = event -> {
			switch (event.type) {
				case SWT.MeasureItem: {
					int column1 = event.index;
					TableItem item1 = (TableItem)event.item;
					Image[] images1 = (Image[])item1.getData(KEY_IMAGES);
					Image image1 = images1[column1];
					if (image1 == null) {
						/* don't change the native-calculated event.width */
						break;
					}
					int[] cachedWidths = (int[])item1.getData(KEY_WIDTHS);
					if (cachedWidths == null) {
						cachedWidths = new int[COLUMN_COUNT];
						item1.setData(KEY_WIDTHS, cachedWidths);
					}
					if (cachedWidths[column1] == 0) {
						int width = image1.getBounds().width + 2 * TEXT_MARGIN;
						GC gc1 = new GC(item1.getParent());
						width += gc1.stringExtent(item1.getText()).x;
						gc1.dispose();
						cachedWidths[column1] = width;
					}
					event.width = cachedWidths[column1];
					break;
				}
				case SWT.EraseItem: {
					int column2 = event.index;
					TableItem item2 = (TableItem)event.item;
					Image[] images2 = (Image[])item2.getData(KEY_IMAGES);
					Image image2 = images2[column2];
					if (image2 == null) {
						break;
					}
					/* disable the native drawing of this item */
					event.detail &= ~SWT.FOREGROUND;
					break;
				}
				case SWT.PaintItem: {
					int column3 = event.index;
					TableItem item3 = (TableItem)event.item;
					Image[] images3 = (Image[])item3.getData(KEY_IMAGES);
					Image image3 = images3[column3];
					if (image3 == null) {
						/* this item is drawn natively, don't touch it*/
						break;
					}

					int x = event.x;
					event.gc.drawImage(image3, x, event.y + (itemHeight - image3.getBounds().height) / 2);
					x += image3.getBounds().width + TEXT_MARGIN;
					event.gc.drawString(item3.getText(column3), x, event.y + (itemHeight - fontHeight) / 2);
					break;
				}
			}
		};
		table.addListener(SWT.MeasureItem, paintListener);
		table.addListener(SWT.EraseItem, paintListener);
		table.addListener(SWT.PaintItem, paintListener);

		for (int i = 0; i < COLUMN_COUNT; i++) {
			table.getColumn(i).pack();
		}

		shell.addDisposeListener(e -> {
			for (int i = 0; i < images.length; i++) {
				if (images[i] != null) {
					images[i].dispose();
				}
			}
		});

		shell.setSize(SWIDTH, SHEIGHT);
		shell.open();
		mainLoop(shell);
	}

	@Test
	public void styledItems_Snippet236() {
		Shell shell = mkShell("Verify tableitems with custom styleText control looks proper & multiple items can be selected");
		shell.setLayout(new FillLayout());
		Table table = new Table(shell, SWT.MULTI | SWT.FULL_SELECTION);
		table.setLinesVisible(true);
		for(int i = 0; i < 10; i++) {
			new TableItem(table, SWT.NONE);
		}
		final TextLayout textLayout = new TextLayout(display);
		textLayout.setText("SWT: Standard Widget Toolkit");
		Font font1 = new Font(display, "Tahoma", 14, SWT.BOLD);
		Font font2 = new Font(display, "Tahoma", 10, SWT.NORMAL);
		Font font3 = new Font(display, "Tahoma", 14, SWT.ITALIC);
		TextStyle style1 = new TextStyle(font1, display.getSystemColor(SWT.COLOR_BLUE), null);
		TextStyle style2 = new TextStyle(font2, display.getSystemColor(SWT.COLOR_MAGENTA), null);
		TextStyle style3 = new TextStyle(font3, display.getSystemColor(SWT.COLOR_RED), null);
		textLayout.setStyle(style1, 0, 0); textLayout.setStyle(style1, 5, 12);
		textLayout.setStyle(style2, 1, 1); textLayout.setStyle(style2, 14, 19);
		textLayout.setStyle(style3, 2, 2); textLayout.setStyle(style3, 21, 27);

		/*
		 * NOTE: MeasureItem, PaintItem and EraseItem are called repeatedly.
		 * Therefore, it is critical for performance that these methods be
		 * as efficient as possible.
		 */
		table.addListener(SWT.PaintItem, event -> textLayout.draw(event.gc, event.x, event.y));
		final Rectangle textLayoutBounds = textLayout.getBounds();
		table.addListener(SWT.MeasureItem, e -> {
			e.width = textLayoutBounds.width + 2;
			e.height = textLayoutBounds.height + 2;
		});
		shell.setSize (SWIDTH, SHEIGHT);
		shell.open();
		shell.addDisposeListener(e -> {
			font1.dispose();
			font2.dispose();
			font3.dispose();
			textLayout.dispose();
		});
		mainLoop(shell);
	}

	@Test
	public void cout_visible_items_Snippet253 ()  {
		final Shell shell = mkShell("Ensure correct item count is displayed in count. Try resizing shell to show 15 items, it should show 15. Gtk3 issues");
		knownToBeBrokenGtk3("On gtk3, the measure is off, see bug 531884");

		FillLayout layout = new FillLayout (SWT.VERTICAL);
		shell.setLayout (layout);
		final Table table = new Table (shell, SWT.NONE);
		for (int i=0; i<32; i++) {
			TableItem item = new TableItem (table, SWT.NONE);
			item.setText ("Item " + (i+1) + " is quite long");
		}
		final Button button = new Button (shell, SWT.PUSH);

		Runnable fixCount = () -> {
			Rectangle rect = table.getClientArea ();
			int itemHeight = table.getItemHeight ();
			int headerHeight = table.getHeaderHeight ();
			int visibleCount = (rect.height - headerHeight + itemHeight - 1) / itemHeight;
			button.setText ("Visible Items [" + visibleCount + "]");
		};

		button.setText ("Visible Items []");
		button.addListener (SWT.Selection, e -> {
			fixCount.run();
		});

		shell.addControlListener(new ControlAdapter() {
			@Override
			public void controlResized(ControlEvent e) {
				fixCount.run();
			}
		});
		shell.addShellListener(new ShellAdapter() {
			@Override
			public void shellActivated(ShellEvent e) {
				fixCount.run();
			}
		});
		// setSize(..)_ affects bug/snippet behaviour.
		shell.setSize(1160, 820); //820 => ~15 items or so, depending on your theme.
		shell.open();
		mainLoop(shell);
	}


	/** Snippet 149 was modified.
	 * - No added columns.
	 * - Button instead of progress bar.
	 */
	@Test
	public void tableEditor_multiple_controls_Snippet149 () {
		knownToBeBrokenGtk3("Snippet is broken on Gtk3. See Bug 531885");
		Shell shell = mkShell("Items should be replaced with Buttons (broken on Gtk3, Bug 531885)");
		shell.setLayout (new FillLayout ());
		Table table = new Table (shell, SWT.BORDER);
		for (int i = 0; i < 20; i++) {
			TableItem item = new TableItem (table, SWT.NONE);
			item.setText ("Task " + i);
			Button button = new Button (table, SWT.NONE);
			button.setText("hello world " + i);
			button.setVisible(true);
			button.addSelectionListener(new SelectionListener() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					System.out.println("Button pressed");
				}
				@Override
				public void widgetDefaultSelected(SelectionEvent e) {
				}
			});
			TableEditor editor = new TableEditor (table);
			editor.grabHorizontal = editor.grabVertical = true;
			editor.setEditor (button, item, 0);
		}
		shell.setSize (SWIDTH, SHEIGHT);
		shell.open();
		mainLoop(shell);
	}


	@Test
	public void tableEditor_dynamically_created_Snippet124()  {
		Shell shell = mkShell("Verify you can edit cells");
		shell.setLayout (new FillLayout ());
		final Table table = new Table(shell, SWT.BORDER | SWT.MULTI);
		table.setLinesVisible (true);
		for (int i=0; i<3; i++) {
			TableColumn column = new TableColumn (table, SWT.NONE);
			column.setWidth(100);
		}
		for (int i=0; i<3; i++) {
			TableItem item = new TableItem (table, SWT.NONE);
			item.setText(new String [] {"" + i, "" + i , "" + i});
		}
		final TableEditor editor = new TableEditor (table);
		editor.horizontalAlignment = SWT.LEFT;
		editor.grabHorizontal = true;
		table.addListener (SWT.MouseDown, event -> {
			Rectangle clientArea = table.getClientArea ();
			Point pt = new Point (event.x, event.y);
			int index = table.getTopIndex ();
			while (index < table.getItemCount ()) {
				boolean visible = false;
				final TableItem item = table.getItem (index);
				for (int i=0; i<table.getColumnCount (); i++) {
					Rectangle rect = item.getBounds (i);
					if (rect.contains (pt)) {
						final int column = i;
						final Text text = new Text (table, SWT.NONE);
						Listener textListener = e -> {
							switch (e.type) {
								case SWT.FocusOut:
									item.setText (column, text.getText ());
									text.dispose ();
									break;
								case SWT.Traverse:
									switch (e.detail) {
										case SWT.TRAVERSE_RETURN:
											item.setText (column, text.getText ());
											//FALL THROUGH
										case SWT.TRAVERSE_ESCAPE:
											text.dispose ();
											e.doit = false;
									}
									break;
							}
						};
						text.addListener (SWT.FocusOut, textListener);
						text.addListener (SWT.Traverse, textListener);
						editor.setEditor (text, item, i);
						text.setText (item.getText (i));
						text.selectAll ();
						text.setFocus ();
						return;
					}
					if (!visible && rect.intersects (clientArea)) {
						visible = true;
					}
				}
				if (!visible) return;
				index++;
			}
		});
		shell.setSize(SWIDTH, SHEIGHT);
		shell.open ();
		mainLoop(shell);
	}
}

