/** * */ package net.frontlinesms.ui; import java.awt.Font; import java.awt.Image; import thinlet.Thinlet; import thinlet.ThinletText; /** * Extension of Thinlet which adds accessors for properties and factory methods for creating components. * @author Alex */ @SuppressWarnings("serial") public class ExtendedThinlet extends Thinlet { private static final String END = "end"; private static final String START = "start"; //> STATIC CONSTANTS //> INSTANCE PROPERTIES //> CONSTRUCTORS //> ACCESSORS //> INSTANCE HELPER METHODS /** * Recursivelty sets a boolean attribute on a UI component and all its sub-components. * @param parent * @param value */ public final void setEnabledRecursively(Object parent, boolean value) { setEnabled(parent, value); for(Object component : getItems(parent)) { if(!getClass(parent).equals(TABLE)) setEnabledRecursively(component, value); } } /** * Recursively sets a boolean attribute on a UI component and all its sub-components. * @param parent * @param value */ public final void setEditableRecursively(Object parent, boolean value) { setEditable(parent, value); for(Object component : getItems(parent)) { if(!getClass(parent).equals(TABLE)) setEditableRecursively(component, value); } } /** * @param component * @return The current position on an editable component */ public final int getCaretPosition(Object component) { return getInteger(component, END); } public final void setCaretPosition(Object component, int caretPosition) { setInteger(component, START, caretPosition); setInteger(component, END, caretPosition); } /** *Sets the Editable property of a component * @param component * @param value */ public void setEditable(Object component, boolean value) { super.setBoolean(component, "editable", value); } //> COMPONENT ACCESSORS /** * Sets the thinlet name of the supplied thinlet component. * @param component * @param name */ public final void setName(Object component, String name) { setString(component, NAME, name); } /** * Attaches an object to a component. * @param component * @param attachment */ public final void setAttachedObject(Object component, Object attachment) { putProperty(component, PROPERTY_ATTACHED_OBJECT, attachment); } /** * Retrieves the attached object from this component. * @param component * @return the object attached to the component, as set by {@link #setAttachedObject(Object, Object)} */ public final Object getAttachedObject(Object component) { return getProperty(component, PROPERTY_ATTACHED_OBJECT); } /** * Retrieves an attached object from a component with the specified class. * @param <T> * @param component * @param clazz * @return An object of the requested class. */ @SuppressWarnings("unchecked") public <T extends Object> T getAttachedObject(Object component, Class<T> clazz) { return (T) getAttachedObject(component); } /** * Disables a UI component and all descended components. * @param component */ public final void deactivate(Object component) { setEnabledRecursively(component, false); } /** * Enables a UI component and all descended components. * @param component */ public final void activate(Object component) { setEnabledRecursively(component, true); } /** * Sets the visibility of a component. * @param component * @param visible */ public void setVisible(Object component, boolean visible) { setBoolean(component, VISIBLE, visible); } /** * Checks if a component is selected. * @param component * @return <code>true</code> if the component is selected */ public boolean isSelected(Object component) { return getBoolean(component, SELECTED); } /** * Checks if a component is enabled. * @param component * @return <code>true</code> if the component is enabled */ public boolean isEnabled(Object component) { return getBoolean(component, ENABLED); } /** * Sets the number of columns of a thinlet component. * @param component * @param columns */ public void setColumns(Object component, int columns) { setInteger(component, ATTRIBUTE_COLUMNS, columns); } /** * Sets the number of rows of a thinlet component. * @param component * @param columns */ public void setRows(Object component, int rows) { setInteger(component, ROWS, rows); } /** * Sets the colspan attribute of a thinlet component. * @param component * @param colspan number of columns for component to span */ public void setColspan(Object component, int colspan) { setInteger(component, ATTRIBUTE_COLSPAN, colspan); } /** * Sets the width of a thinlet component. * @param component * @param width */ public void setWidth(Object component, int width) { setInteger(component, Thinlet.ATTRIBUTE_WIDTH, width); } /** * Sets the height of a thinlet component. * @param component * @param height */ public void setHeight(Object component, int height) { setInteger(component, Thinlet.ATTRIBUTE_HEIGHT, height); } /** * Sets the gap attribute of a thinlet component. * @param component * @param gap gap to add around this component */ public void setGap(Object component, int gap) { setInteger(component, Thinlet.GAP, gap); } /** * Sets the gap attribute of a thinlet component. * @param component * @param weightX horizontal weigth to set for this component * @param weightY vertical weigth to set for this component */ public void setWeight(Object component, int weightX, int weightY) { setInteger(component, Thinlet.ATTRIBUTE_WEIGHT_X, weightX); setInteger(component, Thinlet.ATTRIBUTE_WEIGHT_Y, weightY); } /** * Sets the display of a tree node, expanded or not. * @param node * @param expanded <code>true</code> if the node should be expanded, <code>false</code> otherwise. */ public void setExpanded(Object node, boolean expanded) { setBoolean(node, EXPANDED, expanded); } /** * Sets the icon of a component * @param component * @param icon */ public void setIcon(Object component, Image icon) { setIcon(component, ICON, icon); } /** * Sets the icon of a component from a specified path * @param component * @param iconPath */ public void setIcon(Object component, String iconPath) { setIcon(component, ICON, getIcon(iconPath)); } public void setBold(Object component) { setFont(component, FONT, super.getFont().deriveFont(Font.BOLD)); } /** * Sets whether a component has a border or not * @param component the component to add/remove border from * @param hasBorder <code>true</code> to add border, <code>false</code> to remove */ public void setBorder(Object component, boolean hasBorder) { setBoolean(component, Thinlet.BORDER, hasBorder); } /** * Set the ACTION of a component * @param component * @param methodCall * @param root * @param handler */ public void setAction(Object component, String methodCall, Object root, Object handler) { setMethod(component, Thinlet.ATTRIBUTE_ACTION, methodCall, root, handler); } /** * Set the PERFORM method of a component * @param component * @param methodCall * @param root * @param handler */ public void setPerform(Object component, String methodCall, Object root, ThinletUiEventHandler handler) { setMethod(component, Thinlet.PERFORM, methodCall, root, handler); } /** * Set the DELETE method of a component * @param component * @param methodCall * @param root * @param handler */ public void setDeleteAction(Object component, String methodCall, Object root, Object handler) { setMethod(component, "delete", methodCall, root, handler); } /** * Set the INSERT method of a component * @param component * @param methodCall * @param root * @param handler */ public void setInsert(Object component, String methodCall, Object root, Object handler) { setMethod(component, Thinlet.INSERT, methodCall, root, handler); } /** * Set the REMOVE method of a component * @param component * @param methodCall * @param root * @param handler */ public void setRemove(Object component, String methodCall, Object root, Object handler) { setMethod(component, Thinlet.REMOVE, methodCall, root, handler); } /** * Sets the TOOLTIP of a component * @param component * @param tooltip */ public void setTooltip (Object component, String tooltip) { setString(component, Thinlet.TOOLTIP, tooltip); } /** * Set the CLOSE action of a component * @param component * @param methodCall * @param root * @param handler */ public void setCloseAction(Object component, String methodCall, Object root, Object handler) { setMethod(component, Thinlet.CLOSE, methodCall, root, handler); } /** * Invoke the ACTION method on a component. * @param component The component whose ACTION should be invoked */ public final void invokeAction(Object component) { invoke(component, null, Thinlet.ATTRIBUTE_ACTION); } /** * Sets the horizontal alignment of a component. * @param component The component whose horizontal align will be set. * @param align The alignment value, e.g. {@link ThinletText#LEFT} */ public void setHAlign(Object component, String align) { super.setChoice(component, Thinlet.ATTRIBUTE_HALIGN, align); } /** * Sets the vertical alignment of a component. * @param component The component whose horizontal align will be set. * @param align The alignment value, e.g. {@link ThinletText#LEFT} */ public void setVAlign(Object component, String align) { super.setChoice(component, Thinlet.ATTRIBUTE_VALIGN, align); } //> COMPONENT FACTORY METHODS /** * Creates a Thinlet UI Component of type NODE, sets the component's TEXT * attribute to the supplied text and attaches the supplied OBJECT. * @param text * @param attachedObject * @return a tree node with an object attached to it */ public final Object createNode(String text, Object attachedObject) { Object node = Thinlet.create(NODE); setString(node, TEXT, text); setAttachedObject(node, attachedObject); return node; } /** * Create a Thinlet UI Component of type table row. * @return a table row with an object attached */ public final Object createTableHeader() { Object header = Thinlet.create(HEADER); return header; } /** * Create a Thinlet UI Component of type table row, and attaches the * supplied object to it. * @param attachedObject * @return a table row with an object attached */ public final Object createTableHeader(Object attachedObject) { Object header = createTableHeader(); setAttachedObject(header, attachedObject); return header; } /** * Create a Thinlet UI Component of type table row. * @param attachedObject * @return a table row with an object attached */ public final Object createTableRow() { Object row = Thinlet.create(ROW); return row; } /** * Create a Thinlet UI Component of type table row, and attaches the * supplied object to it. * @param attachedObject * @return a table row with an object attached */ public final Object createTableRow(Object attachedObject) { Object row = createTableRow(); setAttachedObject(row, attachedObject); return row; } /** * Create a Thinlet UI component of type table cell containing the supplied number. * @param integerContent * @return a table cell */ public final Object createTableCell(int integerContent) { return createTableCell(Integer.toString(integerContent)); } /** * Creates a UI table cell component containing the specified text. * @param text * @return a table cell */ public final Object createTableCell(String text) { Object cell = Thinlet.create(CELL); setString(cell, TEXT, text); return cell; } /** * Creates a UI table cell component containing the specified text. * @param text * @return a table cell */ public final Object createTableCell(String text, boolean bold) { Object cell = Thinlet.create(CELL); setString(cell, TEXT, text); if (bold) { Font boldFont = super.getFont().deriveFont(Font.BOLD); setFont(cell, boldFont); } return cell; } /** * Creates a Thinlet UI component of type table cell in the table row provided. * The cell text is also set. * @param row * @param text * @return The cell I created. */ protected final Object createTableCell(Object row, String text) { Object cell = Thinlet.create(CELL); setString(cell, TEXT, text); add(row, cell); return cell; } /** * Creates a Thinlet UI Component of type LIST ITEM, set's the component's * TEXT attribute to the supplied text and attaches the supplied OBJECT. * @param text * @param attachedObject * @return a list item with the supplied attachment */ public final Object createListItem(String text, Object attachedObject) { Object item = Thinlet.create(ITEM); setString(item, TEXT, text); setAttachedObject(item, attachedObject); return item; } /** * Creates a Thinlet UI Component of type LIST ITEM, set's the component's * TEXT attribute to the supplied text and attaches the supplied OBJECT. * @param text * @param attachedObject * @return a list item with the supplied attachment */ public final Object createListItem(String text, Object attachedObject, boolean bold) { Object item = Thinlet.create(ITEM); setString(item, TEXT, text); setAttachedObject(item, attachedObject); if (bold) { Font boldFont = super.getFont().deriveFont(Font.BOLD); setFont(item, boldFont); } return item; } /** * Creates a Thinlet UI Component of type COMBOBOX CHOICE, set's the component's * TEXT attribute to the supplied text and attaches the supplied OBJECT. * @param text * @param attachedObject * @return */ public final Object createComboboxChoice(String text, Object attachedObject) { Object item = Thinlet.create(CHOICE); setString(item, TEXT, text); setAttachedObject(item, attachedObject); return item; } /** * Creates a Thinlet UI Component of type COMBOBOX CHOICE, set's the component's * TEXT attribute to the supplied text and attaches the supplied OBJECT. * @param text * @param attachedObject * @return */ public final Object createColumn(String text, Object attachedObject) { Object item = Thinlet.create(COLUMN); setString(item, TEXT, text); setAttachedObject(item, attachedObject); return item; } /** * Create a modal, closeable and resizeable dialog! * @param title * @return */ public Object createDialog(String title) { Object dialog = Thinlet.create(DIALOG); setString(dialog, TEXT, title); setBoolean(dialog, MODAL, true); setBoolean(dialog, CLOSABLE, true); setBoolean(dialog, "resizable", true); return dialog; } /** * Create's a Thinlet UI Component of type BUTTON and set's the button's * action and text label. * @param text * @param action * @param root * @return */ public final Object createButton(String text, String action, Object root) { Object button = Thinlet.create(BUTTON); setString(button, TEXT, text); setMethod(button, ATTRIBUTE_ACTION, action, root, this); return button; } /** * Create's a Thinlet UI Component of type BUTTON and set's the button's * action and text label. * @param text * @param action * @param root * @return */ public final Object createButton(String text, String action, Object root, ThinletUiEventHandler handler) { Object button = Thinlet.create(BUTTON); setString(button, TEXT, text); setMethod(button, ATTRIBUTE_ACTION, action, root, handler); return button; } /** * Create's a Thinlet UI Component of type BUTTON with type LINK. The button's * action and text label are also set. * @param text * @param action * @param root * @return */ public final Object createLink(String text, String action, Object root) { Object button = createButton(text, action, root); setChoice(button, "type", "link"); return button; } /** * Create's a Thinlet UI Component of type BUTTON with type LINK. The button's * action and text label are also set. * @param text * @param action * @param root * @return */ public final Object createLink(String text, String action, Object root, ThinletUiEventHandler handler) { Object button = createButton(text, action, root, handler); setChoice(button, "type", "link"); return button; } /** * Create's a Thinlet UI Component of type BUTTON and set's the button's * action and text label. * TODO how often is this used? * @param text * @return */ public final Object createButton(String text) { Object button = Thinlet.create(BUTTON); setString(button, TEXT, text); return button; } /** * Create's a Thinlet UI Component of type LABEL with the supplied TEXT. * @param text The text displayed for this label. * @return */ public final Object createLabel(String text) { Object label = create(LABEL); setString(label, TEXT, text); return label; } /** * Create's a Thinlet UI Component of type LABEL with the supplied TEXT. * @param text The text displayed for this label. * @return */ public final Object createLabel(String text, String icon) { Object label = create(LABEL); setString(label, TEXT, text); if (icon != null) { setIcon(label, icon); } return label; } /** * Creates a thinlet Checkbox UI component. * @param text * @param checked * @return */ public final Object createCheckbox(String name, String text, boolean checked) { Object item = create(WIDGET_CHECKBOX); setText(item, text); setName(item, name); setBoolean(item, SELECTED, checked); return item; } /** * Creates a thinlet Radio Button UI component. * @param text * @param checked * @return */ public final Object createRadioButton(String name, String text, String group, boolean selected) { Object item = create(WIDGET_CHECKBOX); setText(item, text); setString(item, GROUP, group); setName(item, name); setBoolean(item, SELECTED, selected); return item; } /** * Creates a thinlet Panel UI component. * @param text * @param checked * @return */ public final Object createPanel(String name) { Object item = Thinlet.create(PANEL); setName(item, name); return item; } /** * Creates a textfield with the supplied object name and initial text. * @param name * @param initialText * @return a Thinlet textfield component */ public final Object createTextfield(String name, String initialText) { Object item = Thinlet.create(TEXTFIELD); setText(item, initialText); setName(item, name); return item; } /** * Creates a textfield with the supplied object name and initial text. * @param name * @param initialText * @return a Thinlet textfield component */ public final Object createTextarea(String name, String initialText, int rows) { Object item = Thinlet.create(TEXTAREA); setText(item, initialText); setName(item, name); setRows(item, rows); return item; } /** * Creates a passwordfield with the supplied object name and initial text. * @param name * @param initialText * @return A Thinlet password entry component */ public final Object createPasswordfield(String name, String initialText) { Object item = Thinlet.create(PASSWORDFIELD); setText(item, initialText); setName(item, name); return item; } /** * @param name * @return A Thinlet Popup Menu */ public final Object createPopupMenu(String name) { Object popupMenu = Thinlet.create(POPUPMENU); setName(popupMenu, name); return popupMenu; } /** * @param iconPath The path to the icon for this menu item * @param text The text for the menuitem * @return A Thinlet menuitem */ public final Object createMenuitem(String iconPath, String text) { Object item = Thinlet.create(MENUITEM); setIcon(item, iconPath); setText(item, text); return item; } /** * @param iconPath The path to the icon for this menu item * @param text The text for the menuitem * @param checked <code>true</code> if the checkbox is ticked, <code>false</code> otherwise. * @return A Thinlet menuitem */ public final Object createCheckboxMenuitem(String iconPath, String text, boolean checked) { Object item = Thinlet.create(CHECKBOXMENUITEM); setIcon(item, iconPath); setSelected(item, checked); setText(item, text); return item; } //> STATIC FACTORIES //> STATIC HELPER METHODS }