/******************************************************************************* * Copyright (c) 2006 Sybase, Inc. and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Sybase, Inc. - initial API and implementation *******************************************************************************/ package org.eclipse.jst.jsf.common.ui.internal.guiutils; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.ControlListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.List; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.Text; /** * This utility class provides convenience methods in creating controls on * preference pages. * * @author mengbo */ public class SWTUtils { // Defaults of controls private static final int DEFAULT_BUTTON_WIDTH = 70; private static final int DEFAULT_COMBO_WIDTH = 100; private static final int DEFAULT_TEXTBOX_WIDTH = 100; private static final int DEFAULT_RADIO_FILL = GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_CENTER; /** * Creates a new checkbox and sets the default layout data. * * @param parent * the composite in which to create the checkbox * @return the new checkbox */ public static Button createCheckBox(Composite parent) { return createCheckBox(parent, null, 1, 0); } /** * Creates a new checkbox and sets the default layout data. * * @param parent * the composite in which to create the checkbox * @param label * the string to set into the checkbox * @param numColumns * the number of columns the new checkbox is to occupy * @return the new checkbox */ public static Button createCheckBox(Composite parent, String label, int numColumns) { return createCheckBox(parent, label, numColumns, 0); } /** * Creates a new checkbox and sets the default layout data. * * @param parent * the composite in which to create the checkbox * @param label * the string to set into the checkbox * @param numColumns * the number of columns the new checkbox is to occupy * @param indent * the number of pixels to indent from the left * @return the new checkbox */ public static Button createCheckBox(Composite parent, String label, int numColumns, int indent) { Button button = new Button(parent, SWT.CHECK | SWT.LEFT); if (label == null) { button.setAlignment(SWT.CENTER); } GridData data = new GridData(GridData.FILL); data.horizontalSpan = numColumns; data.horizontalIndent = indent; button.setLayoutData(data); if (label != null) { button.setText(label); } return button; } /** * Creates a combo box and sets the default layout data. * * @param parent * the composite in which to create the combo * @param items * the items in the combo * @param numColumns * the number of columns the new combo is to occupy * @return the new combo box */ public static Combo createCombo(Composite parent, String[] items, int numColumns) { return createCombo(parent, items, numColumns, DEFAULT_COMBO_WIDTH); } /** * Creates a combo box and sets the default layout data. * * @param parent * the composite in which to create the combo * @param tokenString * a tokenized string that will be split into the fields. * @param numColumns * the number of columns the new combo is to occupy * @return the new combo box */ public static Combo createCombo(Composite parent, String tokenString, int numColumns) { return createCombo(parent, getTokenNames(tokenString), numColumns, DEFAULT_COMBO_WIDTH); } /** * Creates a combo box and sets the default layout data. * * @param parent * the composite in which to create the combo * @param tokenString * a tokenized string that will be split into the fields. * @param numColumns * the number of columns the new combo is to occupy * @param minWidth * minimum width of combo box in pixels * @return the new combo box */ public static Combo createCombo(Composite parent, String tokenString, int numColumns, int minWidth) { return createCombo(parent, getTokenNames(tokenString), numColumns, minWidth); } /** * Creates a combo box and sets the default layout data. * * @param parent * the composite in which to create the combo * @param items * the items in the combo * @param numColumns * the number of columns the new combo is to occupy * @param minWidth * minimum width of combo box in pixels * @return the new combo box */ public static Combo createCombo(Composite parent, String[] items, int numColumns, int minWidth) { return createCombo(parent, items, numColumns, minWidth, false); } /** * Creates a combo box and sets the default layout data. * * @param parent * the composite in which to create the combo * @param tokenString * @param numColumns * the number of columns the new combo is to occupy * @param minWidth * minimum width of combo box in pixels * @param editable * whether the items in the combo is editable * @return the new combo box */ public static Combo createCombo(Composite parent, String tokenString, int numColumns, int minWidth, boolean editable) { return createCombo(parent, getTokenNames(tokenString), numColumns, minWidth, editable); } /** * Creates a combo box and sets the default layout data. * * @param parent * the composite in which to create the combo * @param items * the items in the combo * @param numColumns * the number of columns the new combo is to occupy * @param minWidth * minimum width of combo box in pixels * @param editable * whether the items in the combo is editable * @return the new combo box */ public static Combo createCombo(Composite parent, String[] items, int numColumns, int minWidth, boolean editable) { Combo combo; GridData data; if (editable) { combo = new Combo(parent, SWT.DROP_DOWN); data = new GridData(GridData.FILL_HORIZONTAL); } else { combo = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY); data = new GridData(GridData.FILL); } data.horizontalSpan = numColumns; data.widthHint = minWidth; combo.setLayoutData(data); combo.setItems(items); return combo; } /** * Creates composite control and sets the default layout data. * * @param parent * the parent of the new composite * @param numColumns * the number of columns for the new composite * @return the newly-created coposite */ public static Composite createComposite(Composite parent, int numColumns) { return createComposite(parent, numColumns, -1, -1, GridData.FILL_HORIZONTAL, -1, -1, -1); } /** * Creates composite control and sets the default layout data. * * @param parent * the parent of the new composite * @param numColumns * the number of columns for the new composite * @param verticalSpacing * the spacing between rows. * @param horizontalSpan * the span for this new composite over the original composite. * @return the newly-created coposite */ public static Composite createComposite(Composite parent, int numColumns, int verticalSpacing, int horizontalSpan) { return createComposite(parent, numColumns, verticalSpacing, horizontalSpan, GridData.FILL_HORIZONTAL, -1, -1, -1); } /** * Creates composite control and sets the default layout data. * * @param parent * the parent of the new composite * @param numColumns * the number of columns for the new composite * @param verticalSpacing * the spacing between rows. * @param horizontalSpan * the span for this new composite over the original composite. * @param gridDataFill * the fill to use for this composite. * @return the newly-created coposite */ public static Composite createComposite(Composite parent, int numColumns, int verticalSpacing, int horizontalSpan, int gridDataFill) { return createComposite(parent, numColumns, verticalSpacing, horizontalSpan, gridDataFill, -1, -1, -1); } /** * Creates composite control and sets the default layout data. * * @param parent * the parent of the new composite * @param numColumns * the number of columns for the new composite * @param verticalSpacing * the spacing between rows. * @param horizontalSpan * the span for this new composite over the original composite. * @param gridDataFill * the fill to use for this composite. * @param horizontalSpacing * the spacing between objects. * @param marginWidth * the spacing at start and end of composite. * @param marginHeight * the spacing above and below composite. * @return the newly-created coposite */ public static Composite createComposite(Composite parent, int numColumns, int verticalSpacing, int horizontalSpan, int gridDataFill, int horizontalSpacing, int marginWidth, int marginHeight) { Composite composite = new Composite(parent, SWT.NULL); GridLayout layout = new GridLayout(); layout.numColumns = numColumns; if (verticalSpacing >= 0) { layout.verticalSpacing = verticalSpacing; } if (horizontalSpacing >= 0) { layout.horizontalSpacing = horizontalSpacing; } if (marginWidth >= 0) { layout.marginWidth = marginWidth; } if (marginHeight >= 0) { layout.marginHeight = marginHeight; } composite.setLayout(layout); GridData gd = new GridData(gridDataFill); if (horizontalSpan > 0) { gd.horizontalSpan = horizontalSpan; } composite.setLayoutData(gd); return composite; } /** * Utility method that creates a group and sets the default layout data. * * @param parent * the parent for the new group * @param title * the label for the new group * @param numColumns * the number of columns for the new group * @return the newly created group */ public static Group createGroup(Composite parent, String title, int numColumns) { return createGroup(parent, title, numColumns, -1, GridData.FILL_HORIZONTAL); } /** * Utility method that creates a group and sets the default layout data. * * @param parent * the parent for the new group * @param title * the label for the new group * @param numColumns * the number of columns for the new group * @param horizontalSpan * the number of columns this group should span on the parent * composite. * @param gridDataFill * the fill style of the new group -- set to for filling just * around the object: GridData.BEGINNING | GridData.CENTER * @return the newly created group */ public static Group createGroup(Composite parent, String title, int numColumns, int horizontalSpan, int gridDataFill) { Group group = new Group(parent, SWT.SHADOW_ETCHED_IN); GridLayout layout = new GridLayout(); layout.numColumns = numColumns; group.setLayout(layout); GridData data = new GridData(gridDataFill); if (horizontalSpan > 0) { data.horizontalSpan = horizontalSpan; } group.setLayoutData(data); group.setText(title); return group; } /** * Utility method that creates a label instance and sets the default layout * data. * * @param parent * the parent for the new label * @param text * the text for the new label * @param numColumns * the number of columns for the new composite * @return the new label */ public static Label createLabel(Composite parent, String text, int numColumns) { return createLabel(parent, text, numColumns, 0); } /** * Utility method that creates a label instance and sets the default layout * data. * * @param parent * the parent for the new label * @param text * the text for the new label * @param numColumns * the number of columns for the new composite * @param indent * number of pixels to indent from the left * @return the new label */ public static Label createLabel(Composite parent, String text, int numColumns, int indent) { Label label = new Label(parent, SWT.LEFT); GridData data = new GridData(); data.horizontalSpan = numColumns; data.horizontalAlignment = GridData.FILL; data.horizontalIndent = indent; label.setLayoutData(data); label.setText(text); return label; } /** * Create a image label for sticking in a composite. The backgroud color is * optional. Because images can have "transparent" natures, you might want * to say the background is something other than the defaults composites * background. * * NOTE: the caller is responsible for cleanup of the image and color * objects. * * @param parent * the parent for the new label * @param theImage * the image for the new label * @param numColumns * the number of columns for the new composite * @param background * pass null to use the composites background. * @return the new label */ public static Label createLabelImage(Composite parent, Image theImage, int numColumns, Color background) { Label label = new Label(parent, SWT.LEFT); GridData data = new GridData(); data.horizontalSpan = numColumns; data.horizontalAlignment = GridData.FILL; label.setLayoutData(data); if (background != null) { label.setBackground(background); } label.setImage(theImage); return label; } /** * Utility method that creates a push button instance and sets the default * layout data. * * @param parent * the parent for the new button * @param label * the label for the new button * @return the newly-created button */ public static Button createPushButton(Composite parent, String label) { return createPushButton(parent, label, DEFAULT_BUTTON_WIDTH); } /** * Utility method that creates a push button instance and sets the default * layout data. * * @param parent * the parent for the new button * @param label * the label for the new button * @param widthHint * use this width for the button. * @return the newly-created button */ public static Button createPushButton(Composite parent, String label, int widthHint) { Button button = new Button(parent, SWT.PUSH); GridData data = new GridData(); data.horizontalAlignment = GridData.FILL_HORIZONTAL; data.widthHint = widthHint; button.setLayoutData(data); button.setText(label); return button; } /** * Utility method that creates a push button instance and sets the default * layout data. * * @param parent * the parent for the new button * @param theImage * the label for the new button * @param widthHint * use this width for the button. * @return the newly-created button */ public static Button createPushButton(Composite parent, Image theImage, int widthHint) { Button button = new Button(parent, SWT.PUSH); GridData data = new GridData(); data.horizontalAlignment = GridData.FILL_HORIZONTAL; data.widthHint = widthHint; button.setLayoutData(data); button.setImage(theImage); button.setAlignment(SWT.CENTER); return button; } /** * Utility method that creates a radio button instance and sets the default * layout data. * * @param parent * the parent for the new button * @param label * the label for the new button * @return the newly-created button */ public static Button createRadioButton(Composite parent, String label) { return createRadioButton(parent, label, DEFAULT_RADIO_FILL); } /** * Utility method that creates a radio button instance and sets the default * layout data. * * @param parent * the parent for the new button * @param label * the label for the new button * @param gridDataFill * @return the newly-created button */ public static Button createRadioButton(Composite parent, String label, int gridDataFill) { return createRadioButton(parent, label, gridDataFill, 1); } /** * Utility method that creates a radio button instance and sets the default * layout data. * * @param parent * the parent for the new button * @param label * the label for the new button * @param gridDataFill * @param horizontalSpan * number of columns occupied by button * @return the newly-created button */ public static Button createRadioButton(Composite parent, String label, int gridDataFill, int horizontalSpan) { Button button = new Button(parent, SWT.RADIO | SWT.LEFT); GridData data = new GridData(gridDataFill); data.horizontalSpan = horizontalSpan; button.setLayoutData(data); button.setText(label); return button; } /** * Utility method that creates an empty line * * @param parent * the parent for the new label * @param numColumns * the number of columns for the new composite */ public static void createSpacer(Composite parent, int numColumns) { createSpacer(parent, numColumns, 0); } /** * Utility method that creates an empty line * * @param parent * the parent for the new label * @param numColumns * the number of columns for the new composite * @param minWidth * minimum width of spacer */ public static void createSpacer(Composite parent, int numColumns, int minWidth) { Label label = new Label(parent, SWT.NONE); GridData data = new GridData(); data.horizontalSpan = numColumns; data.widthHint = minWidth; label.setLayoutData(data); } /** * Create a separator that goes across the entire page * * @param parent * the parent for the new label * @param numColumns * the number of columns for the new composite */ public static void createSeparator(Composite parent, int numColumns) { Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); GridData data = new GridData(); data.horizontalSpan = numColumns; data.horizontalAlignment = GridData.FILL; data.grabExcessHorizontalSpace = true; separator.setLayoutData(data); } /** * Create a table from a Composite object * * @param composite * the Composite this table is to be created from * @param tokenString * A string containing names of the columns in the order that * they should be displayed in the table with each column * separated by a comma(',') or null if no columns need to be * created. * @param tablewidth * the minimum width for the table * @param tableHeight * @return the new table */ public static Table createTable(Composite composite, String tokenString, int tablewidth, int tableHeight) { // SINGLE, MULTI, CHECK, FULL_SELECTION, HIDE_SELECTION int style = SWT.V_SCROLL | SWT.H_SCROLL | SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION; Table table = new Table(composite, style); GridData gridData = new GridData(GridData.FILL_BOTH); if (tablewidth > 0) { gridData.widthHint = tablewidth; } if (tableHeight > 0) { gridData.heightHint = tableHeight; } table.setLayoutData(gridData); table.setHeaderVisible(true); table.setLinesVisible(true); if (tokenString != null) { String[] columns = getTokenNames(tokenString); int columnSize = 50; if (tablewidth > 0) { columnSize = tablewidth / columns.length; } for (int ii = 0; ii < columns.length; ii++) { /*(void)*/ createTableColumn(table, columns[ii], ii, columnSize); } } return table; } /** * Create a table from a Composite object * * @param composite * the Composite this table is to be created from * @param columns * A string array containing names of the columns in the order * that they should be displayed in the table, or null if no * columns need to be created. * @param tablewidth * the minimum width for the table * @return the new table */ public static Table createTable(Composite composite, String[] columns, int tablewidth) { int style = SWT.BORDER | SWT.FULL_SELECTION; Table table = new Table(composite, style); GridData gridData = new GridData(GridData.FILL_BOTH); gridData.widthHint = tablewidth; table.setLayoutData(gridData); table.setHeaderVisible(true); table.setLinesVisible(true); if (columns != null) { for (int i = 0; i < columns.length; i++) { /*(void)*/ createTableColumn(table, columns[i], i); } } return table; } /** * Create a table column * * @param parent * the table that contains this column * @param name * name of this column * @param index * the column within the parent composite * @return the new table column */ public static TableColumn createTableColumn(Table parent, String name, int index) { TableColumn column = new TableColumn(parent, SWT.LEFT, index); column.setText(name); return column; } /** * Create a table column with the image and the width of the column is set * to the image width. * * @param parent * the table that contains this column * @param image * iamge for this column * @param index * @return the new table column */ public static TableColumn createTableColumn(Table parent, Image image, int index) { TableColumn column = new TableColumn(parent, SWT.LEFT, index); column.setImage(image); column.setWidth(image.getBounds().width); column.setResizable(false); return column; } /** * Create a table column * * @param parent * the table that contains this column * @param name * name of this column * @param index * the column within the parent composite * @param tablewidth * the width for the column * @return the new table column */ public static TableColumn createTableColumn(Table parent, String name, int index, int tablewidth) { TableColumn column = new TableColumn(parent, SWT.LEFT, index); column.setText(name); column.setWidth(tablewidth); return column; } /** * Create a text field * * @param parent * the parent of the new text field * @return the new text field */ public static Text createTextBox(Composite parent) { return createTextBox(parent, 1, DEFAULT_TEXTBOX_WIDTH); } /** * Create a text field * * @param parent * the parent of the new text field * @param text * @return the new text field */ public static Text createTextBox(Composite parent, String text) { Text textbox = createTextBox(parent, 1); textbox.setText(text); return textbox; } /** * Create a text field * * @param parent * the parent of the new text field * @param numColumns * number of columns the text box is to occupy * @return the new text field */ public static Text createTextBox(Composite parent, int numColumns) { return createTextBox(parent, numColumns, DEFAULT_TEXTBOX_WIDTH); } /** * Create a text field * * @param parent * the parent of the new text field * @param numColumns * number of columns the text box is to occupy * @param minWidth * minimum width of text field * @return the new text field */ public static Text createTextBox(Composite parent, int numColumns, int minWidth) { return createTextBox(parent, numColumns, minWidth, SWT.DEFAULT); } /** * Create a text field * * @param parent * the parent of the new text field * @param numColumns * number of columns the text box is to occupy * @param minWidth * minimum width of text field * @param minHeight * @return the new text field */ public static Text createTextBox(Composite parent, int numColumns, int minWidth, int minHeight) { Text text = new Text(parent, SWT.SINGLE | SWT.BORDER); GridData data = new GridData(GridData.FILL); data.horizontalSpan = numColumns; data.widthHint = minWidth; data.heightHint = minHeight; text.setLayoutData(data); return text; } /** * Create a text field that is scrollable. * * @param parent * the parent of the new text field * @param numColumns * number of columns the text box is to occupy * @param minWidth * minimum width of text field * @param minHeight * minimum height of text field * @return the new text field */ public static Text createTextBoxScrollable(Composite parent, int numColumns, int minWidth, int minHeight) { Text text = new Text(parent, SWT.BORDER | SWT.V_SCROLL | SWT.WRAP); GridData data = new GridData((minWidth > 0) ? GridData.FILL : GridData.FILL_HORIZONTAL); data.horizontalSpan = numColumns; if (minWidth > 0) { data.widthHint = minWidth; } data.heightHint = minHeight; text.setLayoutData(data); return text; } /** * Create a list with the items listed in it. * * @param parent * the parent of the new text field * @param numColumns * number of columns the text box is to occupy * @param minWidth * minimum width of text field * @param minHeight * minimum height of text field * @param items * the items in the list * @return the new list */ public static List createList(Composite parent, int numColumns, int minWidth, int minHeight, String[] items) { return createList(parent, numColumns, minWidth, minHeight, items, true); } /** * Create a list with the items listed in it. * * @param parent * the parent of the new list box * @param numColumns * number of columns the list box is to occupy * @param minWidth * minimum width of list box * @param minHeight * minimum height of list box * @param items * the items in the list * @param bmulti * whether multiple item selection is allowed * @return the new list */ public static List createList(Composite parent, int numColumns, int minWidth, int minHeight, String[] items, boolean bmulti) { return createList(parent, numColumns, minWidth, minHeight, items, bmulti, 1); } /** * Create a list with the items listed in it. * * @param parent * the parent of the new list box * @param numColumns * number of columns the list box is to occupy * @param minWidth * minimum width of list box * @param minHeight * minimum height of list box * @param items * the items in the list * @param bmulti * whether multiple item selection is allowed * @param verticalSpan * the number of rows the list box is to occupy * @return the new list */ public static List createList(Composite parent, int numColumns, int minWidth, int minHeight, String[] items, boolean bmulti, int verticalSpan) { List theList; if (bmulti) theList = new List(parent, SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.BORDER); else theList = new List(parent, SWT.V_SCROLL | SWT.H_SCROLL | SWT.SINGLE | SWT.BORDER); GridData data = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_VERTICAL); data.horizontalSpan = numColumns; data.widthHint = minWidth; data.heightHint = minHeight; data.verticalSpan = verticalSpan; theList.setLayoutData(data); if (items != null) { theList.setItems(items); } return theList; } /** * Computes the size of the composite inside the scroll area so that scroll * bars show up correctly. * * @param parentComposite * @param childComposite */ public static void computeScrollArea(ScrolledComposite parentComposite, Composite childComposite) { // Point pt = childComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT); // childComposite.setSize(pt); Point pt = childComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT); parentComposite.setExpandHorizontal(true); parentComposite.setExpandVertical(true); parentComposite.setMinWidth(pt.x); parentComposite.setMinHeight(pt.y); } /** * Builds an array of strings from a token list string. The token separator * is a comma (','). * * @param tokenString * @return String[] */ public static String[] getTokenNames(String tokenString) { if (tokenString == null) { return new String[0]; } return tokenString.split(","); //$NON-NLS-1$ } /** * Enable/Disable the widget and all its children. * * @param widget * The widget to be enabled/disabled. * @param state * Enable widget if true. Disable otherwise. */ public static void setWidgetState(Control widget, boolean state) { if (widget instanceof Composite) { Control widgets[] = ((Composite) widget).getChildren(); for (int i = 0; i < widgets.length; i++) { setWidgetState(widgets[i], state); } } widget.setEnabled(state); } // --------------------------------------------------------------------------- // following is for workaround eclipse problem // https://bugs.eclipse.org/bugs/show_bug.cgi?id=40281 static ControlListener _listener = new ControlListener() { public void controlResized(ControlEvent e) { final Composite c = (Composite) e.widget; c.getDisplay().asyncExec(new Runnable() { public void run() { if (!c.isDisposed()) { // XXX: in 3.0, should use c.layout(true) // in 3.1, should use c.layout(true, true) c.layout(true); c.redraw(); } } }); } public void controlMoved(ControlEvent e) { // nothing for move } }; /** * @param composite */ public static void workaroundResize(Composite composite) { composite.addControlListener(_listener); } }