/*******************************************************************************
 * Copyright (c) 2000, 2016 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Lars Vogel <Lars.Vogel@vogella.com> - Bug 497575
 *******************************************************************************/
package org.eclipse.swt.examples.controlexample;


import static org.eclipse.swt.events.SelectionListener.widgetDefaultSelectedAdapter;
import static org.eclipse.swt.events.SelectionListener.widgetSelectedAdapter;

import java.lang.reflect.Method;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ArmEvent;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.HelpEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MenuEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TreeEvent;
import org.eclipse.swt.events.TypedEvent;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.ColorDialog;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FontDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Widget;

/**
 * <code>Tab</code> is the abstract superclass of every page
 * in the example's tab folder.  Each page in the tab folder
 * describes a control.
 *
 * A Tab itself is not a control but instead provides a
 * hierarchy with which to share code that is common to
 * every page in the folder.
 *
 * A typical page in a Tab contains a two column composite.
 * The left column contains the "Example" group.  The right
 * column contains "Control" group.  The "Control" group
 * contains controls that allow the user to interact with
 * the example control.  The "Control" group typically
 * contains a "Style", "Other" and "Size" group.  Subclasses
 * can override these defaults to augment a group or stop
 * a group from being created.
 */
abstract class Tab {
	Shell shell;
	Display display;

	/* Common control buttons */
	Button borderButton, enabledButton, visibleButton, backgroundImageButton, popupMenuButton;
	Button preferredButton, tooSmallButton, smallButton, largeButton, rectangleButton, fillHButton, fillVButton;

	/* Common groups and composites */
	Composite tabFolderPage;
	Group exampleGroup, controlGroup, listenersGroup, otherGroup, sizeGroup, styleGroup, colorGroup, backgroundModeGroup;

	/* Controlling instance */
	final ControlExample instance;

	/* Sizing constants for the "Size" group */
	static final int TOO_SMALL_SIZE	= 10;
	static final int RETANGLE_SIZE_WIDTH	= 140;
	static final int RETANGLE_SIZE_HEIGHT	= 30;
	static final int SMALL_SIZE		= 50;
	static final int LARGE_SIZE		= 100;

	/* Right-to-left support */
	static final boolean RTL_SUPPORT_ENABLE = "win32".equals(SWT.getPlatform()) || "gtk".equals(SWT.getPlatform());
	Group orientationGroup;
	Button rtlButton, ltrButton, defaultOrietationButton;
	Group directionGroup;
	Button rtlDirectionButton, ltrDirectionButton, autoDirectionButton, defaultDirectionButton;

	/* Controls and resources for the "Colors & Fonts" group */
	static final int IMAGE_SIZE = 12;
	static final int FOREGROUND_COLOR = 0;
	static final int BACKGROUND_COLOR = 1;
	static final int FONT = 2;
	Table colorAndFontTable;
	ColorDialog colorDialog;
	FontDialog fontDialog;
	Color foregroundColor, backgroundColor;
	Font font;

	/* Controls and resources for the "Background Mode" group */
	Combo backgroundModeCombo;
	Button backgroundModeImageButton, backgroundModeColorButton;

	boolean samplePopup = false;

	/* Set/Get API controls */
	Combo nameCombo;
	Label returnTypeLabel;
	Button getButton, setButton;
	Text setText, getText;
	Shell setGetDialog;

	/* Event logging variables and controls */
	Text eventConsole;
	boolean logging = false;
	boolean untypedEvents = false;
	boolean [] eventsFilter;
	int setFieldsMask = 0;
	Event setFieldsEvent = new Event ();
	boolean ignore = false;

	/* Event logging constants */
	static final int DOIT	= 0x0100;
	static final int DETAIL	= 0x0200;
	static final int TEXT	= 0x0400;
	static final int X		= 0x0800;
	static final int Y		= 0x1000;
	static final int WIDTH	= 0x2000;
	static final int HEIGHT	= 0x4000;

	static final int DETAIL_IME			= 0;
	static final int DETAIL_ERASE_ITEM	= 1;
	static final int DETAIL_TRAVERSE	= 2;

	static class EventInfo {
		String name;
		int type;
		int settableFields;
		int setFields;
		Event event;
		EventInfo (String name, int type, int settableFields, int setFields, Event event) {
			this.name = name;
			this.type = type;
			this.settableFields = settableFields;
			this.setFields = setFields;
			this.event = event;
		}
	}

	final EventInfo [] EVENT_INFO = {
		new EventInfo ("Activate", SWT.Activate, 0, 0, new Event()),
		new EventInfo ("Arm", SWT.Arm, 0, 0, new Event()),
		new EventInfo ("Close", SWT.Close, DOIT, 0, new Event()),
		new EventInfo ("Collapse", SWT.Collapse, 0, 0, new Event()),
		new EventInfo ("Deactivate", SWT.Deactivate, 0, 0, new Event()),
		new EventInfo ("DefaultSelection", SWT.DefaultSelection, 0, 0, new Event()),
		new EventInfo ("Deiconify", SWT.Deiconify, 0, 0, new Event()),
		new EventInfo ("Dispose", SWT.Dispose, 0, 0, new Event()),
		new EventInfo ("DragDetect", SWT.DragDetect, 0, 0, new Event()),
		new EventInfo ("EraseItem", SWT.EraseItem, DETAIL | DETAIL_ERASE_ITEM, 0, new Event()),
		new EventInfo ("Expand", SWT.Expand, 0, 0, new Event()),
		new EventInfo ("FocusIn", SWT.FocusIn, 0, 0, new Event()),
		new EventInfo ("FocusOut", SWT.FocusOut, 0, 0, new Event()),
		new EventInfo ("HardKeyDown", SWT.HardKeyDown, 0, 0, new Event()),
		new EventInfo ("HardKeyUp", SWT.HardKeyUp, 0, 0, new Event()),
		new EventInfo ("Help", SWT.Help, 0, 0, new Event()),
		new EventInfo ("Hide", SWT.Hide, 0, 0, new Event()),
		new EventInfo ("Iconify", SWT.Iconify, 0, 0, new Event()),
		new EventInfo ("KeyDown", SWT.KeyDown, DOIT, 0, new Event()),
		new EventInfo ("KeyUp", SWT.KeyUp, DOIT, 0, new Event()),
		new EventInfo ("MeasureItem", SWT.MeasureItem, 0, 0, new Event()),
		new EventInfo ("MenuDetect", SWT.MenuDetect, X | Y | DOIT, 0, new Event()),
		new EventInfo ("Modify", SWT.Modify, 0, 0, new Event()),
		new EventInfo ("MouseDoubleClick", SWT.MouseDoubleClick, 0, 0, new Event()),
		new EventInfo ("MouseDown", SWT.MouseDown, 0, 0, new Event()),
		new EventInfo ("MouseEnter", SWT.MouseEnter, 0, 0, new Event()),
		new EventInfo ("MouseExit", SWT.MouseExit, 0, 0, new Event()),
		new EventInfo ("MouseHorizontalWheel", SWT.MouseHorizontalWheel, 0, 0, new Event()),
		new EventInfo ("MouseHover", SWT.MouseHover, 0, 0, new Event()),
		new EventInfo ("MouseMove", SWT.MouseMove, 0, 0, new Event()),
		new EventInfo ("MouseUp", SWT.MouseUp, 0, 0, new Event()),
		new EventInfo ("MouseVerticalWheel", SWT.MouseVerticalWheel, 0, 0, new Event()),
		new EventInfo ("Move", SWT.Move, 0, 0, new Event()),
		new EventInfo ("Paint", SWT.Paint, 0, 0, new Event()),
		new EventInfo ("PaintItem", SWT.PaintItem, 0, 0, new Event()),
		new EventInfo ("Resize", SWT.Resize, 0, 0, new Event()),
		new EventInfo ("Selection", SWT.Selection, X | Y | DOIT, 0, new Event()), // sash
		new EventInfo ("SetData", SWT.SetData, 0, 0, new Event()),
//		new EventInfo ("Settings", SWT.Settings, 0, 0, new Event()),  // note: this event only goes to Display
		new EventInfo ("Show", SWT.Show, 0, 0, new Event()),
		new EventInfo ("Traverse", SWT.Traverse, DETAIL | DETAIL_TRAVERSE | DOIT, 0, new Event()),
		new EventInfo ("Verify", SWT.Verify, TEXT | DOIT, 0, new Event()),
		new EventInfo ("ImeComposition", SWT.ImeComposition, DETAIL | DETAIL_IME | TEXT | DOIT, 0, new Event()),
	};

	static final String [][] DETAIL_CONSTANTS = {
		{ // DETAIL_IME = 0
			"SWT.COMPOSITION_CHANGED",
			"SWT.COMPOSITION_OFFSET",
			"SWT.COMPOSITION_SELECTION",
		},
		{ // DETAIL_ERASE_ITEM = 1
			"SWT.SELECTED",
			"SWT.FOCUSED",
			"SWT.BACKGROUND",
			"SWT.FOREGROUND",
			"SWT.HOT",
		},
		{ // DETAIL_TRAVERSE = 2
			"SWT.TRAVERSE_NONE",
			"SWT.TRAVERSE_ESCAPE",
			"SWT.TRAVERSE_RETURN",
			"SWT.TRAVERSE_TAB_PREVIOUS",
			"SWT.TRAVERSE_TAB_NEXT",
			"SWT.TRAVERSE_ARROW_PREVIOUS",
			"SWT.TRAVERSE_ARROW_NEXT",
			"SWT.TRAVERSE_MNEMONIC",
			"SWT.TRAVERSE_PAGE_PREVIOUS",
			"SWT.TRAVERSE_PAGE_NEXT",
		},
	};

	static final Object [] DETAIL_VALUES = {
		"SWT.COMPOSITION_CHANGED", Integer.valueOf(SWT.COMPOSITION_CHANGED),
		"SWT.COMPOSITION_OFFSET", Integer.valueOf(SWT.COMPOSITION_OFFSET),
		"SWT.COMPOSITION_SELECTION", Integer.valueOf(SWT.COMPOSITION_SELECTION),
		"SWT.SELECTED", Integer.valueOf(SWT.SELECTED),
		"SWT.FOCUSED", Integer.valueOf(SWT.FOCUSED),
		"SWT.BACKGROUND", Integer.valueOf(SWT.BACKGROUND),
		"SWT.FOREGROUND", Integer.valueOf(SWT.FOREGROUND),
		"SWT.HOT", Integer.valueOf(SWT.HOT),
		"SWT.TRAVERSE_NONE", Integer.valueOf(SWT.TRAVERSE_NONE),
		"SWT.TRAVERSE_ESCAPE", Integer.valueOf(SWT.TRAVERSE_ESCAPE),
		"SWT.TRAVERSE_RETURN", Integer.valueOf(SWT.TRAVERSE_RETURN),
		"SWT.TRAVERSE_TAB_PREVIOUS", Integer.valueOf(SWT.TRAVERSE_TAB_PREVIOUS),
		"SWT.TRAVERSE_TAB_NEXT", Integer.valueOf(SWT.TRAVERSE_TAB_NEXT),
		"SWT.TRAVERSE_ARROW_PREVIOUS", Integer.valueOf(SWT.TRAVERSE_ARROW_PREVIOUS),
		"SWT.TRAVERSE_ARROW_NEXT", Integer.valueOf(SWT.TRAVERSE_ARROW_NEXT),
		"SWT.TRAVERSE_MNEMONIC", Integer.valueOf(SWT.TRAVERSE_MNEMONIC),
		"SWT.TRAVERSE_PAGE_PREVIOUS", Integer.valueOf(SWT.TRAVERSE_PAGE_PREVIOUS),
		"SWT.TRAVERSE_PAGE_NEXT", Integer.valueOf(SWT.TRAVERSE_PAGE_NEXT),
	};

	/**
	 * Creates the Tab within a given instance of ControlExample.
	 */
	Tab(ControlExample instance) {
		this.instance = instance;
	}

	/**
	 * Creates the "Control" group.  The "Control" group
	 * is typically the right hand column in the tab.
	 */
	void createControlGroup () {

		/*
		 * Create the "Control" group.  This is the group on the
		 * right half of each example tab.  It consists of the
		 * "Style" group, the "Other" group and the "Size" group.
		 */
		controlGroup = new Group (tabFolderPage, SWT.NONE);
		controlGroup.setLayout (new GridLayout (2, true));
		controlGroup.setLayoutData (new GridData(SWT.FILL, SWT.FILL, false, false));
		controlGroup.setText (ControlExample.getResourceString("Parameters"));

		/* Create individual groups inside the "Control" group */
		createStyleGroup ();
		createOtherGroup ();
		createSetGetGroup();
		createSizeGroup ();
		createColorAndFontGroup ();
		if (rtlSupport()) {
			createOrientationGroup ();
			createDirectionGroup ();
		}
		createBackgroundModeGroup ();

		/*
		 * For each Button child in the style group, add a selection
		 * listener that will recreate the example controls.  If the
		 * style group button is a RADIO button, ensure that the radio
		 * button is selected before recreating the example controls.
		 * When the user selects a RADIO button, the current RADIO
		 * button in the group is deselected and the new RADIO button
		 * is selected automatically.  The listeners are notified for
		 * both these operations but typically only do work when a RADIO
		 * button is selected.
		 */
		SelectionListener selectionListener = widgetSelectedAdapter(event -> {
			if ((event.widget.getStyle () & SWT.RADIO) != 0) {
				if (!((Button) event.widget).getSelection ()) return;
			}
			if (!handleTextDirection (event.widget)) {
				recreateExampleWidgets ();
				if (rtlSupport ()) {
					/* Reflect the base direction falls back to the default (i.e. orientation). */
					ltrDirectionButton.setSelection (false);
					rtlDirectionButton.setSelection (false);
					autoDirectionButton.setSelection (false);
					defaultDirectionButton.setSelection (true);
				}
			}
		});
		Control [] children = styleGroup.getChildren ();
		for (Control child : children) {
			if (child instanceof Button) {
				Button button = (Button) child;
				button.addSelectionListener (selectionListener);
			} else {
				if (child instanceof Composite) {
					/* Look down one more level of children in the style group. */
					Composite composite = (Composite) child;
					Control [] grandchildren = composite.getChildren ();
					for (Control grandchild : grandchildren) {
						if (grandchild instanceof Button) {
							Button button = (Button) grandchild;
							button.addSelectionListener (selectionListener);
						}
					}
				}
			}
		}
		if (rtlSupport()) {
			rtlButton.addSelectionListener (selectionListener);
			ltrButton.addSelectionListener (selectionListener);
			defaultOrietationButton.addSelectionListener (selectionListener);
			rtlDirectionButton.addSelectionListener (selectionListener);
			ltrDirectionButton.addSelectionListener (selectionListener);
			autoDirectionButton.addSelectionListener (selectionListener);
			defaultDirectionButton.addSelectionListener (selectionListener);
		}
	}

	/**
	 * Append the Set/Get API controls to the "Other" group.
	 */
	void createSetGetGroup() {
		/*
		 * Create the button to access set/get API functionality.
		 */
		final String [] methodNames = getMethodNames ();
		if (methodNames != null) {
			final Button setGetButton = new Button (otherGroup, SWT.PUSH);
			setGetButton.setText (ControlExample.getResourceString ("Set_Get"));
			setGetButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
			setGetButton.addSelectionListener (widgetSelectedAdapter(e -> {
				if (getExampleWidgets().length >  0) {
					if (setGetDialog == null) {
						setGetDialog = createSetGetDialog(methodNames);
					}
					Point pt = setGetButton.getLocation();
					pt = display.map(setGetButton.getParent(), null, pt);
					setGetDialog.setLocation(pt.x, pt.y);
					setGetDialog.open();
				}
			}));
		}
	}

	/**
	 * Creates the "Control" widget children.
	 * Subclasses override this method to augment
	 * the standard controls created in the "Style",
	 * "Other" and "Size" groups.
	 */
	void createControlWidgets () {
	}

	/**
	 * Creates the "Colors and Fonts" group. This is typically
	 * a child of the "Control" group. Subclasses override
	 * this method to customize color and font settings.
	 */
	void createColorAndFontGroup () {
		/* Create the group. */
		colorGroup = new Group(controlGroup, SWT.NONE);
		colorGroup.setLayout (new GridLayout (2, true));
		colorGroup.setLayoutData (new GridData (SWT.FILL, SWT.FILL, false, false));
		colorGroup.setText (ControlExample.getResourceString ("Colors"));
		colorAndFontTable = new Table(colorGroup, SWT.BORDER | SWT.V_SCROLL);
		colorAndFontTable.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false, 2, 1));
		TableItem item = new TableItem(colorAndFontTable, SWT.None);
		item.setText(ControlExample.getResourceString ("Foreground_Color"));
		colorAndFontTable.setSelection(0);
		item = new TableItem(colorAndFontTable, SWT.None);
		item.setText(ControlExample.getResourceString ("Background_Color"));
		item = new TableItem(colorAndFontTable, SWT.None);
		item.setText(ControlExample.getResourceString ("Font"));
		Button changeButton = new Button (colorGroup, SWT.PUSH);
		changeButton.setText(ControlExample.getResourceString("Change"));
		changeButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
		Button defaultsButton = new Button (colorGroup, SWT.PUSH);
		defaultsButton.setText(ControlExample.getResourceString("Defaults"));
		defaultsButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));

		/* Add listeners to set/reset colors and fonts. */
		colorDialog = new ColorDialog (shell);
		fontDialog = new FontDialog (shell);
		colorAndFontTable.addSelectionListener(widgetDefaultSelectedAdapter(event -> changeFontOrColor (colorAndFontTable.getSelectionIndex())));
		changeButton.addSelectionListener(widgetSelectedAdapter(event -> changeFontOrColor (colorAndFontTable.getSelectionIndex())));
		defaultsButton.addSelectionListener(widgetSelectedAdapter(e -> resetColorsAndFonts ()));
		shell.addDisposeListener(event -> {
			if (foregroundColor != null) foregroundColor.dispose();
			if (backgroundColor != null) backgroundColor.dispose();
			if (font != null) font.dispose();
			foregroundColor = null;
			backgroundColor = null;
			font = null;
			if (colorAndFontTable != null && !colorAndFontTable.isDisposed()) {
				TableItem [] items = colorAndFontTable.getItems();
				for (TableItem currentItem : items) {
					Image image = currentItem.getImage();
					if (image != null) image.dispose();
				}
			}
		});
	}

	void changeFontOrColor(int index) {
		switch (index) {
			case FOREGROUND_COLOR: {
				Color oldColor = foregroundColor;
				if (oldColor == null) {
					Control [] controls = getExampleControls ();
					if (controls.length > 0) oldColor = controls [0].getForeground ();
				}
				if (oldColor != null) colorDialog.setRGB(oldColor.getRGB()); // seed dialog with current color
				RGB rgb = colorDialog.open();
				if (rgb == null) return;
				oldColor = foregroundColor; // save old foreground color to dispose when done
				foregroundColor = new Color (display, rgb);
				setExampleWidgetForeground ();
				if (oldColor != null) oldColor.dispose ();
			}
			break;
			case BACKGROUND_COLOR: {
				Color oldColor = backgroundColor;
				if (oldColor == null) {
					Control [] controls = getExampleControls ();
					if (controls.length > 0) oldColor = controls [0].getBackground (); // seed dialog with current color
				}
				if (oldColor != null) colorDialog.setRGB(oldColor.getRGB());
				RGB rgb = colorDialog.open();
				if (rgb == null) return;
				oldColor = backgroundColor; // save old background color to dispose when done
				backgroundColor = new Color (display, rgb);
				setExampleWidgetBackground ();
				if (oldColor != null) oldColor.dispose ();
			}
			break;
			case FONT: {
				Font oldFont = font;
				if (oldFont == null) {
					Control [] controls = getExampleControls ();
					if (controls.length > 0) oldFont = controls [0].getFont ();
				}
				if (oldFont != null) fontDialog.setFontList(oldFont.getFontData()); // seed dialog with current font
				FontData fontData = fontDialog.open ();
				if (fontData == null) return;
				oldFont = font; // dispose old font when done
				font = new Font (display, fontData);
				setExampleWidgetFont ();
				setExampleWidgetSize ();
				if (oldFont != null) oldFont.dispose ();
			}
			break;
		}
	}

	/**
	 * Creates the "Other" group.  This is typically
	 * a child of the "Control" group.
	 */
	void createOtherGroup () {
		/* Create the group */
		otherGroup = new Group (controlGroup, SWT.NONE);
		otherGroup.setLayout (new GridLayout ());
		otherGroup.setLayoutData (new GridData (SWT.FILL, SWT.FILL, false, false));
		otherGroup.setText (ControlExample.getResourceString("Other"));

		/* Create the controls */
		enabledButton = new Button(otherGroup, SWT.CHECK);
		enabledButton.setText(ControlExample.getResourceString("Enabled"));
		visibleButton = new Button(otherGroup, SWT.CHECK);
		visibleButton.setText(ControlExample.getResourceString("Visible"));
		backgroundImageButton = new Button(otherGroup, SWT.CHECK);
		backgroundImageButton.setText(ControlExample.getResourceString("BackgroundImage"));
		popupMenuButton = new Button(otherGroup, SWT.CHECK);
		popupMenuButton.setText(ControlExample.getResourceString("PopupMenu"));

		/* Add the listeners */
		enabledButton.addSelectionListener (widgetSelectedAdapter(event -> setExampleWidgetEnabled ()));
		visibleButton.addSelectionListener (widgetSelectedAdapter(event -> setExampleWidgetVisibility ()));
		backgroundImageButton.addSelectionListener (widgetSelectedAdapter(event -> setExampleWidgetBackgroundImage ()));
		popupMenuButton.addSelectionListener (widgetSelectedAdapter(event -> setExampleWidgetPopupMenu ()));

		/* Set the default state */
		enabledButton.setSelection(true);
		visibleButton.setSelection(true);
		backgroundImageButton.setSelection(false);
		popupMenuButton.setSelection(false);
	}

	/**
	 * Creates the "Background Mode" group.
	 */
	void createBackgroundModeGroup () {
		/* Create the group */
		backgroundModeGroup = new Group (controlGroup, SWT.NONE);
		backgroundModeGroup.setLayout (new GridLayout ());
		backgroundModeGroup.setLayoutData (new GridData (SWT.FILL, SWT.FILL, false, false));
		backgroundModeGroup.setText (ControlExample.getResourceString("Background_Mode"));

		/* Create the controls */
		backgroundModeCombo = new Combo(backgroundModeGroup, SWT.READ_ONLY);
		backgroundModeCombo.setItems("SWT.INHERIT_NONE", "SWT.INHERIT_DEFAULT", "SWT.INHERIT_FORCE");
		backgroundModeImageButton = new Button(backgroundModeGroup, SWT.CHECK);
		backgroundModeImageButton.setText(ControlExample.getResourceString("BackgroundImage"));
		backgroundModeColorButton = new Button(backgroundModeGroup, SWT.CHECK);
		backgroundModeColorButton.setText(ControlExample.getResourceString("BackgroundColor"));

		/* Add the listeners */
		backgroundModeCombo.addSelectionListener (widgetSelectedAdapter(event -> setExampleGroupBackgroundMode ()));
		backgroundModeImageButton.addSelectionListener (widgetSelectedAdapter(event -> setExampleGroupBackgroundImage ()));
		backgroundModeColorButton.addSelectionListener (widgetSelectedAdapter(event -> setExampleGroupBackgroundColor ()));

		/* Set the default state */
		backgroundModeCombo.setText(backgroundModeCombo.getItem(0));
		backgroundModeImageButton.setSelection(false);
		backgroundModeColorButton.setSelection(false);
	}

	void createEditEventDialog(Shell parent, int x, int y, final int index) {
		final Shell dialog = new Shell(parent, SWT.DIALOG_TRIM | SWT.RESIZE | SWT.APPLICATION_MODAL);
		dialog.setLayout(new GridLayout());
		dialog.setText(ControlExample.getResourceString ("Edit_Event"));
		Label label = new Label (dialog, SWT.NONE);
		label.setText (ControlExample.getResourceString ("Edit_Event_Fields", EVENT_INFO[index].name));

		Group group = new Group (dialog, SWT.NONE);
		group.setLayout(new GridLayout(2, false));
		group.setLayoutData(new GridData (SWT.FILL, SWT.FILL, true, true));

		final int fields = EVENT_INFO[index].settableFields;
		final int eventType = EVENT_INFO[index].type;
		setFieldsMask = EVENT_INFO[index].setFields;
		setFieldsEvent = EVENT_INFO[index].event;

		if ((fields & DOIT) != 0) {
			new Label (group, SWT.NONE).setText ("doit");
			final Combo doitCombo = new Combo (group, SWT.READ_ONLY);
			doitCombo.setItems ("", "true", "false");
			if ((setFieldsMask & DOIT) != 0) doitCombo.setText(Boolean.toString(setFieldsEvent.doit));
			doitCombo.setLayoutData (new GridData (SWT.FILL, SWT.CENTER, true, false));
			doitCombo.addSelectionListener(widgetSelectedAdapter(e -> {
				String newValue = doitCombo.getText();
				if (newValue.length() == 0) {
					setFieldsMask &= ~DOIT;
				} else {
					setFieldsEvent.type = eventType;
					setFieldsEvent.doit = newValue.equals("true");
					setFieldsMask |= DOIT;
				}
			}));
		}

		if ((fields & DETAIL) != 0) {
			new Label (group, SWT.NONE).setText ("detail");
			int detailType = fields & 0xFF;
			final Combo detailCombo = new Combo (group, SWT.READ_ONLY);
			detailCombo.setItems (DETAIL_CONSTANTS[detailType]);
			detailCombo.add ("", 0);
			detailCombo.setVisibleItemCount(detailCombo.getItemCount());
			if ((setFieldsMask & DETAIL) != 0) detailCombo.setText (DETAIL_CONSTANTS[detailType][setFieldsEvent.detail]);
			detailCombo.setLayoutData (new GridData (SWT.FILL, SWT.CENTER, true, false));
			detailCombo.addSelectionListener(widgetSelectedAdapter(e -> {
				String newValue = detailCombo.getText();
				if (newValue.length() == 0) {
					setFieldsMask &= ~DETAIL;
				} else {
					setFieldsEvent.type = eventType;
					for (int i = 0; i < DETAIL_VALUES.length; i += 2) {
						if (newValue.equals (DETAIL_VALUES [i])) {
							setFieldsEvent.detail = ((Integer) DETAIL_VALUES [i + 1]).intValue();
							break;
						}
					}
					setFieldsMask |= DETAIL;
				}
			}));
		}

		if ((fields & TEXT) != 0) {
			new Label (group, SWT.NONE).setText ("text");
			final Text textText = new Text (group, SWT.BORDER);
			if ((setFieldsMask & TEXT) != 0) textText.setText(setFieldsEvent.text);
			textText.setLayoutData (new GridData (SWT.FILL, SWT.CENTER, true, false));
			textText.addModifyListener(e -> {
				String newValue = textText.getText();
				if (newValue.length() == 0) {
					setFieldsMask &= ~TEXT;
				} else {
					setFieldsEvent.type = eventType;
					setFieldsEvent.text = newValue;
					setFieldsMask |= TEXT;
				}
			});
		}

		if ((fields & X) != 0) {
			new Label (group, SWT.NONE).setText ("x");
			final Text xText = new Text (group, SWT.BORDER);
			if ((setFieldsMask & X) != 0) xText.setText(Integer.toString(setFieldsEvent.x));
			xText.setLayoutData (new GridData (SWT.FILL, SWT.CENTER, true, false));
			xText.addModifyListener(e -> {
				String newValue = xText.getText ();
				try {
					int newIntValue = Integer.parseInt (newValue);
					setFieldsEvent.type = eventType;
					setFieldsEvent.x = newIntValue;
					setFieldsMask |= X;
				} catch (NumberFormatException ex) {
					setFieldsMask &= ~X;
				}
			});
		}

		if ((fields & Y) != 0) {
			new Label (group, SWT.NONE).setText ("y");
			final Text yText = new Text (group, SWT.BORDER);
			if ((setFieldsMask & Y) != 0) yText.setText(Integer.toString(setFieldsEvent.y));
			yText.setLayoutData (new GridData (SWT.FILL, SWT.CENTER, true, false));
			yText.addModifyListener(e -> {
				String newValue = yText.getText ();
				try {
					int newIntValue = Integer.parseInt (newValue);
					setFieldsEvent.type = eventType;
					setFieldsEvent.y = newIntValue;
					setFieldsMask |= Y;
				} catch (NumberFormatException ex) {
					setFieldsMask &= ~Y;
				}
			});
		}

		if ((fields & WIDTH) != 0) {
			new Label (group, SWT.NONE).setText ("width");
			final Text widthText = new Text (group, SWT.BORDER);
			if ((setFieldsMask & WIDTH) != 0) widthText.setText(Integer.toString(setFieldsEvent.width));
			widthText.setLayoutData (new GridData (SWT.FILL, SWT.CENTER, true, false));
			widthText.addModifyListener(e -> {
				String newValue = widthText.getText ();
				try {
					int newIntValue = Integer.parseInt (newValue);
					setFieldsEvent.type = eventType;
					setFieldsEvent.width = newIntValue;
					setFieldsMask |= WIDTH;
				} catch (NumberFormatException ex) {
					setFieldsMask &= ~WIDTH;
				}
			});
		}

		if ((fields & HEIGHT) != 0) {
			new Label (group, SWT.NONE).setText ("height");
			final Text heightText = new Text (group, SWT.BORDER);
			if ((setFieldsMask & HEIGHT) != 0) heightText.setText(Integer.toString(setFieldsEvent.height));
			heightText.setLayoutData (new GridData (SWT.FILL, SWT.CENTER, true, false));
			heightText.addModifyListener(e -> {
				String newValue = heightText.getText ();
				try {
					int newIntValue = Integer.parseInt (newValue);
					setFieldsEvent.type = eventType;
					setFieldsEvent.height = newIntValue;
					setFieldsMask |= HEIGHT;
				} catch (NumberFormatException ex) {
					setFieldsMask &= ~HEIGHT;
				}
			});
		}

		Button ok = new Button (dialog, SWT.PUSH);
		ok.setText (ControlExample.getResourceString("OK"));
		GridData data = new GridData (70, SWT.DEFAULT);
		data.horizontalAlignment = SWT.RIGHT;
		ok.setLayoutData (data);
		ok.addSelectionListener (widgetSelectedAdapter(e -> {
			EVENT_INFO[index].setFields = setFieldsMask;
			EVENT_INFO[index].event = setFieldsEvent;
			dialog.dispose();
		}));

		dialog.setDefaultButton(ok);
		dialog.pack();
		dialog.setLocation(x, y);
		dialog.open();
	}

	/**
	 * Create the event console popup menu.
	 */
	void createEventConsolePopup () {
		Menu popup = new Menu (shell, SWT.POP_UP);
		eventConsole.setMenu (popup);

		MenuItem cut = new MenuItem (popup, SWT.PUSH);
		cut.setText (ControlExample.getResourceString("MenuItem_Cut"));
		cut.addListener (SWT.Selection, event -> eventConsole.cut ());
		MenuItem copy = new MenuItem (popup, SWT.PUSH);
		copy.setText (ControlExample.getResourceString("MenuItem_Copy"));
		copy.addListener (SWT.Selection, event -> eventConsole.copy ());
		MenuItem paste = new MenuItem (popup, SWT.PUSH);
		paste.setText (ControlExample.getResourceString("MenuItem_Paste"));
		paste.addListener (SWT.Selection, event -> eventConsole.paste ());
		new MenuItem (popup, SWT.SEPARATOR);
		MenuItem selectAll = new MenuItem (popup, SWT.PUSH);
		selectAll.setText(ControlExample.getResourceString("MenuItem_SelectAll"));
		selectAll.addListener (SWT.Selection, event -> eventConsole.selectAll ());
	}

	/**
	 * Creates the "Example" group.  The "Example" group
	 * is typically the left hand column in the tab.
	 */
	void createExampleGroup () {
		exampleGroup = new Group (tabFolderPage, SWT.NONE);
		exampleGroup.setLayout (new GridLayout ());
		exampleGroup.setLayoutData (new GridData (SWT.FILL, SWT.FILL, true, true));
	}

	/**
	 * Creates the "Example" widget children of the "Example" group.
	 * Subclasses override this method to create the particular
	 * example control.
	 */
	void createExampleWidgets () {
		/* Do nothing */
	}

	/**
	 * Creates and opens the "Listener selection" dialog.
	 */
	void createListenerSelectionDialog () {
		final Shell dialog = new Shell (shell, SWT.DIALOG_TRIM | SWT.RESIZE | SWT.APPLICATION_MODAL);
		dialog.setText (ControlExample.getResourceString ("Select_Listeners"));
		dialog.setLayout (new GridLayout (2, false));
		final Table table = new Table (dialog, SWT.BORDER | SWT.V_SCROLL | SWT.CHECK);
		GridData data = new GridData(GridData.FILL_BOTH);
		data.verticalSpan = 3;
		table.setLayoutData(data);
		for (int i = 0; i < EVENT_INFO.length; i++) {
			TableItem item = new TableItem (table, SWT.NONE);
			item.setText (EVENT_INFO[i].name);
			item.setChecked (eventsFilter[i]);
		}
		final String [] customNames = getCustomEventNames ();
		for (int i = 0; i < customNames.length; i++) {
			TableItem item = new TableItem (table, SWT.NONE);
			item.setText (customNames[i]);
			item.setChecked (eventsFilter[EVENT_INFO.length + i]);
		}
		Button selectAll = new Button (dialog, SWT.PUSH);
		selectAll.setText(ControlExample.getResourceString ("Select_All"));
		selectAll.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
		selectAll.addSelectionListener (widgetSelectedAdapter(e -> {
			TableItem [] items = table.getItems();
			for (int i = 0; i < EVENT_INFO.length; i++) {
				items[i].setChecked(true);
			}
			for (int i = 0; i < customNames.length; i++) {
				items[EVENT_INFO.length + i].setChecked(true);
			}
		}));
		Button deselectAll = new Button (dialog, SWT.PUSH);
		deselectAll.setText(ControlExample.getResourceString ("Deselect_All"));
		deselectAll.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
		deselectAll.addSelectionListener (widgetSelectedAdapter(e -> {
			TableItem [] items = table.getItems();
			for (int i = 0; i < EVENT_INFO.length; i++) {
				items[i].setChecked(false);
			}
			for (int i = 0; i < customNames.length; i++) {
				items[EVENT_INFO.length + i].setChecked(false);
			}
		}));
		final Button editEvent = new Button (dialog, SWT.PUSH);
		editEvent.setText (ControlExample.getResourceString ("Edit_Event"));
		editEvent.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_BEGINNING));
		editEvent.addSelectionListener (widgetSelectedAdapter(e -> {
			Point pt = editEvent.getLocation();
			pt = e.display.map(editEvent, null, pt);
			int index = table.getSelectionIndex();
			if (getExampleWidgets().length > 0 && index != -1) {
				createEditEventDialog(dialog, pt.x, pt.y, index);
			}
		}));
		editEvent.setEnabled(false);
		table.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				int fields = 0;
				int index = table.getSelectionIndex();
				if (index != -1 && index < EVENT_INFO.length) {  // TODO: Allow custom widgets to specify event info
					fields = (EVENT_INFO[index].settableFields);
				}
				editEvent.setEnabled(fields != 0);
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				if (editEvent.getEnabled()) {
					Point pt = editEvent.getLocation();
					pt = e.display.map(editEvent, null, pt);
					int index = table.getSelectionIndex();
					if (getExampleWidgets().length > 0 && index != -1 && index < EVENT_INFO.length) {
						createEditEventDialog(dialog, pt.x, pt.y, index);
					}
				}
			}
		});

		new Label(dialog, SWT.NONE); /* Filler */
		Button ok = new Button (dialog, SWT.PUSH);
		ok.setText(ControlExample.getResourceString ("OK"));
		dialog.setDefaultButton(ok);
		ok.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
		ok.addSelectionListener (widgetSelectedAdapter(e -> {
			TableItem [] items = table.getItems();
			for (int i = 0; i < EVENT_INFO.length; i++) {
				eventsFilter[i] = items[i].getChecked();
			}
			for (int i = 0; i < customNames.length; i++) {
				eventsFilter[EVENT_INFO.length + i] = items[EVENT_INFO.length + i].getChecked();
			}
			dialog.dispose();
		}));
		dialog.pack ();
		/*
		 * If the preferred size of the dialog is too tall for the display,
		 * then reduce the height, so that the vertical scrollbar will appear.
		 */
		Rectangle bounds = dialog.getBounds();
		Rectangle trim = dialog.computeTrim(0, 0, 0, 0);
		Rectangle clientArea = display.getClientArea();
		if (bounds.height > clientArea.height) {
			dialog.setSize(bounds.width, clientArea.height - trim.height);
		}
		dialog.setLocation(bounds.x, clientArea.y);
		dialog.open ();
		while (! dialog.isDisposed()) {
			if (! display.readAndDispatch()) display.sleep();
		}
	}

	/**
	 * Creates the "Listeners" group.  The "Listeners" group
	 * goes below the "Example" and "Control" groups.
	 */
	void createListenersGroup () {
		listenersGroup = new Group (tabFolderPage, SWT.NONE);
		listenersGroup.setLayout (new GridLayout (4, false));
		listenersGroup.setLayoutData (new GridData (SWT.FILL, SWT.FILL, true, true, 2, 1));
		listenersGroup.setText (ControlExample.getResourceString ("Listeners"));

		/*
		 * Create the button to access the 'Listeners' dialog.
		 */
		Button listenersButton = new Button (listenersGroup, SWT.PUSH);
		listenersButton.setText (ControlExample.getResourceString ("Select_Listeners"));
		listenersButton.addSelectionListener (widgetSelectedAdapter(e -> {
			createListenerSelectionDialog ();
			recreateExampleWidgets ();
		}));

		/*
		 * Create the checkbox to specify whether typed or untyped events are displayed in the log.
		 */
		final Button untypedEventsCheckbox = new Button (listenersGroup, SWT.CHECK);
		untypedEventsCheckbox.setText (ControlExample.getResourceString ("UntypedEvents"));
		untypedEventsCheckbox.addSelectionListener (widgetSelectedAdapter(e -> untypedEvents = untypedEventsCheckbox.getSelection ()));

		/*
		 * Create the checkbox to add/remove listeners to/from the example widgets.
		 */
		final Button listenCheckbox = new Button (listenersGroup, SWT.CHECK);
		listenCheckbox.setText (ControlExample.getResourceString ("Listen"));
		listenCheckbox.addSelectionListener (widgetSelectedAdapter(e -> {
			logging = listenCheckbox.getSelection ();
			recreateExampleWidgets ();
		}));

		/*
		 * Create the button to clear the text.
		 */
		Button clearButton = new Button (listenersGroup, SWT.PUSH);
		clearButton.setText (ControlExample.getResourceString ("Clear"));
		clearButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
		clearButton.addSelectionListener (widgetSelectedAdapter(e -> eventConsole.setText ("")));

		/* Initialize the eventsFilter to log all events. */
		int customEventCount = getCustomEventNames ().length;
		eventsFilter = new boolean [EVENT_INFO.length + customEventCount];
		for (int i = 0; i < EVENT_INFO.length + customEventCount; i++) {
			eventsFilter [i] = true;
		}

		/* Create the event console Text. */
		eventConsole = new Text (listenersGroup, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
		GridData data = new GridData (GridData.FILL_BOTH);
		data.horizontalSpan = 4;
		data.heightHint = 80;
		eventConsole.setLayoutData (data);
		createEventConsolePopup ();
		eventConsole.addKeyListener (new KeyAdapter () {
			@Override
			public void keyPressed (KeyEvent e) {
				if ((e.keyCode == 'A' || e.keyCode == 'a') && (e.stateMask & SWT.MOD1) != 0) {
					eventConsole.selectAll ();
					e.doit = false;
				}
			}
		});
	}

	/**
	 * Returns a list of set/get API method names (without the set/get prefix)
	 * that can be used to set/get values in the example control(s).
	 */
	String[] getMethodNames() {
		return null;
	}

	Shell createSetGetDialog(String[] methodNames) {
		final Shell dialog = new Shell(shell, SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MODELESS);
		dialog.setLayout(new GridLayout(2, false));
		dialog.setText(getTabText() + " " + ControlExample.getResourceString ("Set_Get"));
		nameCombo = new Combo(dialog, SWT.READ_ONLY);
		nameCombo.setItems(methodNames);
		nameCombo.setText(methodNames[0]);
		nameCombo.setVisibleItemCount(methodNames.length);
		nameCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
		nameCombo.addSelectionListener(widgetSelectedAdapter(e -> resetLabels()));
		returnTypeLabel = new Label(dialog, SWT.NONE);
		returnTypeLabel.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, false, false));
		setButton = new Button(dialog, SWT.PUSH);
		setButton.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, false, false));
		setButton.addSelectionListener(widgetSelectedAdapter(e -> {
			setValue();
			setText.selectAll();
			setText.setFocus();
		}));
		setText = new Text(dialog, SWT.SINGLE | SWT.BORDER);
		setText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
		getButton = new Button(dialog, SWT.PUSH);
		getButton.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, false, false));
		getButton.addSelectionListener(widgetSelectedAdapter(e -> getValue()));
		getText = new Text(dialog, SWT.MULTI | SWT.BORDER | SWT.READ_ONLY | SWT.H_SCROLL | SWT.V_SCROLL);
		GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
		data.widthHint = 240;
		data.heightHint = 200;
		getText.setLayoutData(data);
		resetLabels();
		dialog.setDefaultButton(setButton);
		dialog.pack();
		dialog.addDisposeListener(e -> setGetDialog = null);
		return dialog;
	}

	void resetLabels() {
		String methodRoot = nameCombo.getText();
		returnTypeLabel.setText(parameterInfo(methodRoot));
		setButton.setText(setMethodName(methodRoot));
		getButton.setText("get" + methodRoot);
		setText.setText("");
		getText.setText("");
		getValue();
		setText.setFocus();
	}

	String setMethodName(String methodRoot) {
		return "set" + methodRoot;
	}

	String parameterInfo(String methodRoot) {
		String typeName = null;
		Class<?> returnType = getReturnType(methodRoot);
		boolean isArray = returnType.isArray();
		if (isArray) {
			typeName = returnType.getComponentType().getName();
		} else {
			typeName = returnType.getName();
		}
		String typeNameString = typeName;
		int index = typeName.lastIndexOf('.');
		if (index != -1 && index+1 < typeName.length()) typeNameString = typeName.substring(index+1);
		String info = ControlExample.getResourceString("Info_" + typeNameString + (isArray ? "A" : ""));
		if (isArray) {
			typeNameString += "[]";
		}
		return ControlExample.getResourceString("Parameter_Info", new Object[] {typeNameString, info});
	}

	void getValue() {
		String methodName = "get" + nameCombo.getText();
		getText.setText("");
		Widget[] widgets = getExampleWidgets();
		for (int i = 0; i < widgets.length; i++) {
			try {
				if (widgets[i] == null) {
					continue;
				}
				Method method = widgets[i].getClass().getMethod(methodName);
				Object result = method.invoke(widgets[i]);
				if (result == null) {
					getText.append("null");
				} else if (result.getClass().isArray()) {
					int length = java.lang.reflect.Array.getLength(result);
					if (length == 0) {
						getText.append(result.getClass().getComponentType() + "[0]");
					}
					for (int j = 0; j < length; j++) {
						getText.append(java.lang.reflect.Array.get(result,j).toString() + "\n");
					}
				} else {
					getText.append(result.toString());
				}
			} catch (Exception e) {
				getText.append(e.toString());
			}
			if (i + 1 < widgets.length) {
				getText.append("\n\n");
			}
		}
	}

	Class<?> getReturnType(String methodRoot) {
		Class<?> returnType = null;
		String methodName = "get" + methodRoot;
		Widget[] widgets = getExampleWidgets();
		try {
			Method method = widgets[0].getClass().getMethod(methodName);
			returnType = method.getReturnType();
		} catch (Exception e) {
		}
		return returnType;
	}

	void setValue() {
		/* The parameter type must be the same as the get method's return type */
		String methodRoot = nameCombo.getText();
		Class<?> returnType = getReturnType(methodRoot);
		String methodName = setMethodName(methodRoot);
		String value = setText.getText();
		Widget[] widgets = getExampleWidgets();
		for (Widget widget : widgets) {
			try {
				if (widget == null) {
					continue;
				}
				java.lang.reflect.Method method = widget.getClass().getMethod(methodName, returnType);
				String typeName = returnType.getName();
				Object[] parameter = null;
				if (value.equals("null")) {
					parameter = new Object[] {null};
				} else if (typeName.equals("int")) {
					parameter = new Object[] {Integer.valueOf(value)};
				} else if (typeName.equals("long")) {
					parameter = new Object[] {Long.valueOf(value)};
				} else if (typeName.equals("char")) {
					parameter = new Object[] {value.length() == 1 ? Character.valueOf(value.charAt(0)) : Character.valueOf('\0')};
				} else if (typeName.equals("boolean")) {
					parameter = new Object[] {Boolean.valueOf(value)};
				} else if (typeName.equals("java.lang.String")) {
					parameter = new Object[] {value};
				} else if (typeName.equals("org.eclipse.swt.graphics.Point")) {
					String xy[] = split(value, ',');
					parameter = new Object[] {new Point(Integer.parseInt(xy[0]),Integer.parseInt(xy[1]))};
				} else if (typeName.equals("org.eclipse.swt.graphics.Rectangle")) {
					String xywh[] = split(value, ',');
					parameter = new Object[] {new Rectangle(Integer.parseInt(xywh[0]),Integer.parseInt(xywh[1]),Integer.parseInt(xywh[2]),Integer.parseInt(xywh[3]))};
				} else if (typeName.equals("[I")) {
					String strings[] = split(value, ',');
					int[] ints = new int[strings.length];
					for (int j = 0; j < strings.length; j++) {
						ints[j] = Integer.valueOf(strings[j]).intValue();
					}
					parameter = new Object[] {ints};
				} else if (typeName.equals("[C")) {
					String strings[] = split(value, ',');
					char[] chars = new char[strings.length];
					for (int j = 0; j < strings.length; j++) {
						chars[j] = strings[j].charAt(0);
					}
					parameter = new Object[] {chars};
				} else if (typeName.equals("[Ljava.lang.String;")) {
					parameter = new Object[] {split(value, ',')};
				} else {
					parameter = parameterForType(typeName, value, widget);
				}
				method.invoke(widget, parameter);
			} catch (Exception e) {
				Throwable cause = e.getCause();
				String message = e.getMessage();
				getText.setText(e.toString());
				if (cause != null) getText.append(", cause=\n" + cause.toString());
				if (message != null) getText.append(", message=\n" + message);
			}
		}
	}

	Object[] parameterForType(String typeName, String value, Widget widget) {
		return new Object[] {value};
	}

	void createOrientationGroup () {
		/* Create Orientation group*/
		orientationGroup = new Group (controlGroup, SWT.NONE);
		orientationGroup.setLayout (new GridLayout());
		orientationGroup.setLayoutData (new GridData (SWT.FILL, SWT.FILL, false, false));
		orientationGroup.setText (ControlExample.getResourceString("Orientation"));
		defaultOrietationButton = new Button (orientationGroup, SWT.RADIO);
		defaultOrietationButton.setText (ControlExample.getResourceString("Default"));
		defaultOrietationButton.setSelection (true);
		ltrButton = new Button (orientationGroup, SWT.RADIO);
		ltrButton.setText ("SWT.LEFT_TO_RIGHT");
		rtlButton = new Button (orientationGroup, SWT.RADIO);
		rtlButton.setText ("SWT.RIGHT_TO_LEFT");
	}

	void createDirectionGroup () {
		/* Create Text Direction group*/
		directionGroup = new Group (controlGroup, SWT.NONE);
		directionGroup.setLayout (new GridLayout());
		directionGroup.setLayoutData (new GridData (SWT.FILL, SWT.FILL, false, false));
		directionGroup.setText (ControlExample.getResourceString("Text_Direction"));
		defaultDirectionButton = new Button (directionGroup, SWT.RADIO);
		defaultDirectionButton.setText (ControlExample.getResourceString("Default"));
		defaultDirectionButton.setSelection (true);
		ltrDirectionButton = new Button (directionGroup, SWT.RADIO);
		ltrDirectionButton.setText ("SWT.LEFT_TO_RIGHT");
		rtlDirectionButton = new Button (directionGroup, SWT.RADIO);
		rtlDirectionButton.setText ("SWT.RIGHT_TO_LEFT");
		autoDirectionButton = new Button (directionGroup, SWT.RADIO);
		autoDirectionButton.setText ("AUTO direction");
	}

	/**
	 * Creates the "Size" group.  The "Size" group contains
	 * controls that allow the user to change the size of
	 * the example widgets.
	 */
	void createSizeGroup () {
		/* Create the group */
		sizeGroup = new Group (controlGroup, SWT.NONE);
		sizeGroup.setLayout (new GridLayout());
		sizeGroup.setLayoutData (new GridData (SWT.FILL, SWT.FILL, false, false));
		sizeGroup.setText (ControlExample.getResourceString("Size"));

		/* Create the controls */

		/*
		 * The preferred size of a widget is the size returned
		 * by widget.computeSize (SWT.DEFAULT, SWT.DEFAULT).
		 * This size is defined on a widget by widget basis.
		 * Many widgets will attempt to display their contents.
		 */
		preferredButton = new Button (sizeGroup, SWT.RADIO);
		preferredButton.setText (ControlExample.getResourceString("Preferred"));
		tooSmallButton = new Button (sizeGroup, SWT.RADIO);
		tooSmallButton.setText (TOO_SMALL_SIZE + " X " + TOO_SMALL_SIZE);
		smallButton = new Button(sizeGroup, SWT.RADIO);
		smallButton.setText (SMALL_SIZE + " X " + SMALL_SIZE);
		largeButton = new Button (sizeGroup, SWT.RADIO);
		largeButton.setText (LARGE_SIZE + " X " + LARGE_SIZE);
		rectangleButton = new Button (sizeGroup, SWT.RADIO);
		rectangleButton.setText (RETANGLE_SIZE_WIDTH + " X " + RETANGLE_SIZE_HEIGHT);
		fillHButton = new Button (sizeGroup, SWT.CHECK);
		fillHButton.setText (ControlExample.getResourceString("Fill_X"));
		fillVButton = new Button (sizeGroup, SWT.CHECK);
		fillVButton.setText (ControlExample.getResourceString("Fill_Y"));

		/* Add the listeners */
		SelectionListener selectionListener = widgetSelectedAdapter(event -> setExampleWidgetSize ());
		preferredButton.addSelectionListener(selectionListener);
		tooSmallButton.addSelectionListener(selectionListener);
		smallButton.addSelectionListener(selectionListener);
		largeButton.addSelectionListener(selectionListener);
		rectangleButton.addSelectionListener(selectionListener);
		fillHButton.addSelectionListener(selectionListener);
		fillVButton.addSelectionListener(selectionListener);

		/* Set the default state */
		preferredButton.setSelection (true);
	}

	/**
	 * Creates the "Style" group.  The "Style" group contains
	 * controls that allow the user to change the style of
	 * the example widgets.  Changing a widget "Style" causes
	 * the widget to be destroyed and recreated.
	 */
	void createStyleGroup () {
		styleGroup = new Group (controlGroup, SWT.NONE);
		styleGroup.setLayout (new GridLayout ());
		styleGroup.setLayoutData (new GridData (SWT.FILL, SWT.FILL, false, false));
		styleGroup.setText (ControlExample.getResourceString("Styles"));
	}

	/**
	 * Creates the tab folder page.
	 *
	 * @param tabFolder org.eclipse.swt.widgets.TabFolder
	 * @return the new page for the tab folder
	 */
	Composite createTabFolderPage (TabFolder tabFolder) {
		/* Cache the shell and display. */
		shell = tabFolder.getShell ();
		display = shell.getDisplay ();

		/* Create a two column page. */
		tabFolderPage = new Composite (tabFolder, SWT.NONE);
		tabFolderPage.setLayout (new GridLayout (2, false));

		/* Create the "Example" and "Control" groups. */
		createExampleGroup ();
		createControlGroup ();

		/* Create the "Listeners" group under the "Control" group. */
		createListenersGroup ();

		/* Create and initialize the example and control widgets. */
		createExampleWidgets ();
		hookExampleWidgetListeners ();
		createControlWidgets ();
		setExampleWidgetState ();

		return tabFolderPage;
	}

	void setExampleWidgetPopupMenu() {
		Control[] controls = getExampleControls();
		for (final Control control : controls) {
			control.addListener(SWT.MenuDetect, event -> {
				Menu menu = control.getMenu();
				if (menu != null && samplePopup) {
					menu.dispose();
					menu = null;
				}
				if (menu == null && popupMenuButton.getSelection()) {
					menu = new Menu(shell, SWT.POP_UP | (control.getStyle() & (SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT)));
					MenuItem item = new MenuItem(menu, SWT.PUSH);
					item.setText("Sample popup menu item");
					specialPopupMenuItems(menu, event);
					control.setMenu(menu);
					samplePopup = true;
				}
			});
		}
	}

	protected void specialPopupMenuItems(final Menu menu, final Event event) {
	}

	/**
	 * Disposes the "Example" widgets.
	 */
	void disposeExampleWidgets () {
		Widget [] widgets = getExampleWidgets ();
		for (Widget widget : widgets) {
			widget.dispose ();
		}
	}

	Image colorImage (Color color) {
		Image image = new Image (display, IMAGE_SIZE, IMAGE_SIZE);
		GC gc = new GC(image);
		gc.setBackground(color);
		Rectangle bounds = image.getBounds();
		gc.fillRectangle(0, 0, bounds.width, bounds.height);
		gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
		gc.drawRectangle(0, 0, bounds.width - 1, bounds.height - 1);
		gc.dispose();
		return image;
	}

	Image fontImage (Font font) {
		Image image = new Image (display, IMAGE_SIZE, IMAGE_SIZE);
		GC gc = new GC(image);
		Rectangle bounds = image.getBounds();
		gc.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
		gc.fillRectangle(0, 0, bounds.width, bounds.height);
		gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
		gc.drawRectangle(0, 0, bounds.width - 1, bounds.height - 1);
		FontData data[] = font.getFontData();
		int style = data[0].getStyle();
		switch (style) {
		case SWT.NORMAL:
			gc.drawLine(3, 3, 3, 8);
			gc.drawLine(4, 3, 7, 8);
			gc.drawLine(8, 3, 8, 8);
			break;
		case SWT.BOLD:
			gc.drawLine(3, 2, 3, 9);
			gc.drawLine(4, 2, 4, 9);
			gc.drawLine(5, 2, 7, 2);
			gc.drawLine(5, 3, 8, 3);
			gc.drawLine(5, 5, 7, 5);
			gc.drawLine(5, 6, 7, 6);
			gc.drawLine(5, 8, 8, 8);
			gc.drawLine(5, 9, 7, 9);
			gc.drawLine(7, 4, 8, 4);
			gc.drawLine(7, 7, 8, 7);
			break;
		case SWT.ITALIC:
			gc.drawLine(6, 2, 8, 2);
			gc.drawLine(7, 3, 4, 8);
			gc.drawLine(3, 9, 5, 9);
			break;
		case SWT.BOLD | SWT.ITALIC:
			gc.drawLine(5, 2, 8, 2);
			gc.drawLine(5, 3, 8, 3);
			gc.drawLine(6, 4, 4, 7);
			gc.drawLine(7, 4, 5, 7);
			gc.drawLine(3, 8, 6, 8);
			gc.drawLine(3, 9, 6, 9);
			break;
		}
		gc.dispose();
		return image;
	}

	/**
	 * Gets the list of custom event names.
	 * Subclasses override this method to allow adding of custom events.
	 *
	 * @return an array containing custom event names
	 * @see hookCustomListener
	 */
	String [] getCustomEventNames () {
		return new String [0];
	}

	/**
	 * Gets the default style for a widget
	 *
	 * @return the default style bit
	 */
	int getDefaultStyle () {
		if (ltrButton != null && ltrButton.getSelection()) {
			return SWT.LEFT_TO_RIGHT;
		}
		if (rtlButton != null && rtlButton.getSelection()) {
			return SWT.RIGHT_TO_LEFT;
		}
		return SWT.NONE;
	}

	/**
	 * Gets the "Example" widgets.
	 *
	 * @return an array containing the example widgets
	 */
	Widget [] getExampleWidgets () {
		return new Widget [0];
	}

	/**
	 * Gets the "Example" controls.
	 * This is the subset of "Example" widgets that are controls.
	 *
	 * @return an array containing the example controls
	 */
	Control [] getExampleControls () {
		Widget [] widgets = getExampleWidgets ();
		Control [] controls = new Control [0];
		for (Widget widget : widgets) {
			if (widget instanceof Control) {
				Control[] newControls = new Control[controls.length + 1];
				System.arraycopy(controls, 0, newControls, 0, controls.length);
				controls = newControls;
				controls[controls.length - 1] = (Control)widget;
			}
		}
		return controls;
	}

	/**
	 * Gets the "Example" widget's items, if any.
	 *
	 * @return an array containing the example widget's items
	 */
	Item [] getExampleWidgetItems () {
		return new Item [0];
	}

	/**
	 * Gets the short text for the tab folder item.
	 *
	 * @return the short text for the tab item
	 */
	String getShortTabText() {
		return getTabText();
	}

	/**
	 * Gets the text for the tab folder item.
	 *
	 * @return the text for the tab item
	 */
	String getTabText () {
		return "";
	}

	/**
	 * In case one of the buttons that control text direction was selected,
	 * apply the text direction on the controls in the client area.
	 *
	 * @return false iff example widgets must be re-created
	 */
	boolean handleTextDirection (Widget widget) {
		if (!rtlSupport ()) {
			return false;
		}
		int textDirection = SWT.NONE;
		if (ltrDirectionButton.equals (widget)) {
			textDirection = SWT.LEFT_TO_RIGHT;
		} else if (rtlDirectionButton.equals (widget)) {
			textDirection = SWT.RIGHT_TO_LEFT;
		} else if (autoDirectionButton.equals (widget)) {
			textDirection = SWT.AUTO_TEXT_DIRECTION;
		} else if (!defaultDirectionButton.equals (widget)) {
			return false;
		}
		Control [] children = getExampleControls ();
		if (children.length > 0) {
			if (SWT.NONE == textDirection) {
				textDirection = children [0].getOrientation ();
			}
			for (Control child : children) {
				child.setTextDirection (textDirection);
			}
		}
		return true;
	}

	/**
	 * Hooks all listeners to all example controls
	 * and example control items.
	 */
	void hookExampleWidgetListeners () {
		if (logging) {
			Widget[] widgets = getExampleWidgets ();
			for (Widget widget : widgets) {
				hookListeners (widget);
			}
			Item[] exampleItems = getExampleWidgetItems ();
			for (Item exampleItem : exampleItems) {
				hookListeners (exampleItem);
			}
			String [] customNames = getCustomEventNames ();
			for (int i = 0; i < customNames.length; i++) {
				if (eventsFilter [EVENT_INFO.length + i]) {
					hookCustomListener (customNames[i]);
				}
			}
		}
	}

	/**
	 * Hooks the custom listener specified by eventName.
	 * Subclasses override this method to add custom listeners.
	 * @see getCustomEventNames
	 */
	void hookCustomListener (String eventName) {
	}

	/**
	 * Hooks all listeners to the specified widget.
	 */
	void hookListeners (Widget widget) {
		if (logging) {
			Listener listener = event -> log (event);
			for (int i = 0; i < EVENT_INFO.length; i++) {
				if (eventsFilter [i]) {
					widget.addListener (EVENT_INFO[i].type, listener);
				}
			}
		}
	}

	/**
	 * Logs an untyped event to the event console.
	 */
	void log(Event event) {
		int i = 0;
		while (i < EVENT_INFO.length) {
			if (EVENT_INFO[i].type == event.type) break;
			i++;
		}
		String toString = EVENT_INFO[i].name + " [" + event.type + "]: ";
		if (!untypedEvents) {
			switch (event.type) {
				case SWT.KeyDown:
				case SWT.KeyUp: toString += new KeyEvent (event).toString (); break;
				case SWT.MouseDown:
				case SWT.MouseUp:
				case SWT.MouseMove:
				case SWT.MouseEnter:
				case SWT.MouseExit:
				case SWT.MouseDoubleClick:
				case SWT.MouseWheel:
				case SWT.MouseHover: toString += new MouseEvent (event).toString (); break;
				case SWT.Paint: toString += new PaintEvent (event).toString (); break;
				case SWT.Move:
				case SWT.Resize: toString += new ControlEvent (event).toString (); break;
				case SWT.Dispose: toString += new DisposeEvent (event).toString (); break;
				case SWT.Selection:
				case SWT.DefaultSelection: toString += new SelectionEvent (event).toString (); break;
				case SWT.FocusIn:
				case SWT.FocusOut: toString += new FocusEvent (event).toString (); break;
				case SWT.Expand:
				case SWT.Collapse: toString += new TreeEvent (event).toString (); break;
				case SWT.Iconify:
				case SWT.Deiconify:
				case SWT.Close:
				case SWT.Activate:
				case SWT.Deactivate: toString += new ShellEvent (event).toString (); break;
				case SWT.Show:
				case SWT.Hide: toString += (event.widget instanceof Menu) ? new MenuEvent (event).toString () : event.toString(); break;
				case SWT.Modify: toString += new ModifyEvent (event).toString (); break;
				case SWT.Verify: toString += new VerifyEvent (event).toString (); break;
				case SWT.Help: toString += new HelpEvent (event).toString (); break;
				case SWT.Arm: toString += new ArmEvent (event).toString (); break;
				case SWT.Traverse: toString += new TraverseEvent (event).toString (); break;
				case SWT.HardKeyDown:
				case SWT.HardKeyUp:
				case SWT.DragDetect:
				case SWT.MenuDetect:
				case SWT.SetData:
				default: toString += event.toString ();
			}
		} else {
			toString += event.toString();
		}
		log (toString);

		/* Return values for event fields. */
		int mask = EVENT_INFO[i].setFields;
		if (!ignore && mask != 0) {
			Event setFieldsEvent = EVENT_INFO[i].event;
			if ((mask & DOIT) != 0) event.doit = setFieldsEvent.doit;
			if ((mask & DETAIL) != 0) event.detail = setFieldsEvent.detail;
			if ((mask & TEXT) != 0) event.text = setFieldsEvent.text;
			if ((mask & X) != 0) event.x = setFieldsEvent.x;
			if ((mask & Y) != 0) event.y = setFieldsEvent.y;
			if ((mask & WIDTH) != 0) event.width = setFieldsEvent.width;
			if ((mask & HEIGHT) != 0) event.height = setFieldsEvent.height;
			eventConsole.append (ControlExample.getResourceString("Returning"));
			ignore = true;
			log (event);
			ignore = false;
		}
	}

	/**
	 * Logs a string to the event console.
	 */
	void log (String string) {
		if (!eventConsole.isDisposed()) {
			eventConsole.append (string);
			eventConsole.append ("\n");
		}
	}

	/**
	 * Logs a typed event to the event console.
	 */
	void log (String eventName, TypedEvent event) {
		log (eventName + ": " + event.toString ());
	}

	/**
	 * Recreates the "Example" widgets.
	 */
	void recreateExampleWidgets () {
		disposeExampleWidgets ();
		createExampleWidgets ();
		hookExampleWidgetListeners ();
		setExampleWidgetState ();
	}

	/**
	 * Sets the foreground color, background color, and font
	 * of the "Example" widgets to their default settings.
	 * Subclasses may extend in order to reset other colors
	 * and fonts to default settings as well.
	 */
	void resetColorsAndFonts () {
		Color oldColor = foregroundColor;
		foregroundColor = null;
		setExampleWidgetForeground ();
		if (oldColor != null) oldColor.dispose();
		oldColor = backgroundColor;
		backgroundColor = null;
		setExampleWidgetBackground ();
		if (oldColor != null) oldColor.dispose();
		Font oldFont = font;
		font = null;
		setExampleWidgetFont ();
		setExampleWidgetSize ();
		if (oldFont != null) oldFont.dispose();
	}

	boolean rtlSupport() {
		return RTL_SUPPORT_ENABLE;
	}

	/**
	 * Sets the background color of the "Example" widgets' parent.
	 */
	void setExampleGroupBackgroundColor () {
		if (backgroundModeGroup == null) return;
		exampleGroup.setBackground (backgroundModeColorButton.getSelection () ? display.getSystemColor(SWT.COLOR_BLUE) : null);
	}
	/**
	 * Sets the background image of the "Example" widgets' parent.
	 */
	void setExampleGroupBackgroundImage () {
		if (backgroundModeGroup == null) return;
		exampleGroup.setBackgroundImage (backgroundModeImageButton.getSelection () ? instance.images[ControlExample.ciParentBackground] : null);
	}

	/**
	 * Sets the background mode of the "Example" widgets' parent.
	 */
	void setExampleGroupBackgroundMode () {
		if (backgroundModeGroup == null) return;
		String modeString = backgroundModeCombo.getText ();
		int mode = SWT.INHERIT_NONE;
		if (modeString.equals("SWT.INHERIT_DEFAULT")) mode = SWT.INHERIT_DEFAULT;
		if (modeString.equals("SWT.INHERIT_FORCE")) mode = SWT.INHERIT_FORCE;
		exampleGroup.setBackgroundMode (mode);
	}

	/**
	 * Sets the background color of the "Example" widgets.
	 */
	void setExampleWidgetBackground () {
		if (colorAndFontTable == null) return; // user cannot change color/font on this tab
		Control [] controls = getExampleControls ();
		if (!instance.startup) {
			for (Control control : controls) {
				control.setBackground (backgroundColor);
			}
		}
		// Set the background color item's image to match the background color of the example widget(s).
		Color color = backgroundColor;
		if (controls.length == 0) return;
		if (color == null) color = controls [0].getBackground ();
		TableItem item = colorAndFontTable.getItem(BACKGROUND_COLOR);
		Image oldImage = item.getImage();
		if (oldImage != null) oldImage.dispose();
		item.setImage (colorImage (color));
	}

	/**
	 * Sets the enabled state of the "Example" widgets.
	 */
	void setExampleWidgetEnabled () {
		Control [] controls = getExampleControls ();
		for (Control control : controls) {
			control.setEnabled (enabledButton.getSelection ());
		}
	}

	/**
	 * Sets the font of the "Example" widgets.
	 */
	void setExampleWidgetFont () {
		if (colorAndFontTable == null) return; // user cannot change color/font on this tab
		Control [] controls = getExampleControls ();
		if (!instance.startup) {
			for (Control control : controls) {
				control.setFont(font);
			}
		}
		/* Set the font item's image and font to match the font of the example widget(s). */
		Font ft = font;
		if (controls.length == 0) return;
		if (ft == null) ft = controls [0].getFont ();
		TableItem item = colorAndFontTable.getItem(FONT);
		Image oldImage = item.getImage();
		if (oldImage != null) oldImage.dispose();
		item.setImage (fontImage (ft));
		item.setFont(ft);
		colorAndFontTable.layout ();
	}

	/**
	 * Sets the foreground color of the "Example" widgets.
	 */
	void setExampleWidgetForeground () {
		if (colorAndFontTable == null) return; // user cannot change color/font on this tab
		Control [] controls = getExampleControls ();
		if (!instance.startup) {
			for (Control control : controls) {
				control.setForeground (foregroundColor);
			}
		}
		/* Set the foreground color item's image to match the foreground color of the example widget(s). */
		Color color = foregroundColor;
		if (controls.length == 0) return;
		if (color == null) color = controls [0].getForeground ();
		TableItem item = colorAndFontTable.getItem(FOREGROUND_COLOR);
		Image oldImage = item.getImage();
		if (oldImage != null) oldImage.dispose();
		item.setImage (colorImage(color));
	}

	/**
	 * Sets the size of the "Example" widgets.
	 */
	void setExampleWidgetSize () {
		int size = SWT.DEFAULT;
		if (preferredButton == null) return;
		if (preferredButton.getSelection()) size = SWT.DEFAULT;
		if (tooSmallButton.getSelection()) size = TOO_SMALL_SIZE;
		if (smallButton.getSelection()) size = SMALL_SIZE;
		if (largeButton.getSelection()) size = LARGE_SIZE;
		Control [] controls = getExampleControls ();
		for (Control control : controls) {
			GridData gridData = new GridData(size, size);
			if (rectangleButton.getSelection()) {
				gridData = new GridData(RETANGLE_SIZE_WIDTH, RETANGLE_SIZE_HEIGHT);
			}
			gridData.grabExcessHorizontalSpace = fillHButton.getSelection();
			gridData.grabExcessVerticalSpace = fillVButton.getSelection();
			gridData.horizontalAlignment = fillHButton.getSelection() ? SWT.FILL : SWT.LEFT;
			gridData.verticalAlignment = fillVButton.getSelection() ? SWT.FILL : SWT.TOP;
			control.setLayoutData (gridData);
		}
		tabFolderPage.layout (controls);
	}

	/**
	 * Sets the state of the "Example" widgets.  Subclasses
	 * may extend this method to set "Example" widget state
	 * that is specific to the widget.
	 */
	void setExampleWidgetState () {
		setExampleWidgetBackground ();
		setExampleWidgetForeground ();
		setExampleWidgetFont ();
		if (!instance.startup) {
			setExampleWidgetEnabled ();
			setExampleWidgetVisibility ();
			setExampleGroupBackgroundMode ();
			setExampleGroupBackgroundColor ();
			setExampleGroupBackgroundImage ();
			setExampleWidgetBackgroundImage ();
			setExampleWidgetPopupMenu ();
			setExampleWidgetSize ();
		}
		//TEMPORARY CODE
//		Control [] controls = getExampleControls ();
//		for (int i=0; i<controls.length; i++) {
//			log ("Control=" + controls [i] + ", border width=" + controls [i].getBorderWidth ());
//		}
	}

	/**
	 * Sets the visibility of the "Example" widgets.
	 */
	void setExampleWidgetVisibility () {
		Control [] controls = getExampleControls ();
		for (Control control : controls) {
			control.setVisible (visibleButton.getSelection ());
		}
	}

	/**
	 * Sets the background image of the "Example" widgets.
	 */
	void setExampleWidgetBackgroundImage () {
		if (backgroundImageButton != null && backgroundImageButton.isDisposed()) return;
		Control [] controls = getExampleControls ();
		for (Control control : controls) {
			control.setBackgroundImage (backgroundImageButton.getSelection () ? instance.images[ControlExample.ciBackground] : null);
		}
	}

	/**
	 * Splits the given string around matches of the given character.
	 *
	 * This subset of java.lang.String.split(String regex)
	 * uses only code that can be run on CLDC platforms.
	 */
	String [] split (String string, char ch) {
		String [] result = new String[0];
		int start = 0;
		int length = string.length();
		while (start < length) {
			int end = string.indexOf(ch, start);
			if (end == -1) end = length;
			String substr = string.substring(start, end);
			String [] newResult = new String[result.length + 1];
			System.arraycopy(result, 0, newResult, 0, result.length);
			newResult [result.length] = substr;
			result = newResult;
			start = end + 1;
		}
		return result;
	}
}
