From 40cbef33e1c69f1c912d6a21968bcc8455476289 Mon Sep 17 00:00:00 2001
From: Matti Tahvonen
* There are two modes - vertical and horizontal.
*
@@ -44,7 +48,7 @@ import com.itmill.toolkit.terminal.Resource;
* @since 3.0
*/
public class Table extends AbstractSelect implements Action.Container,
- Container.Ordered, Container.Sortable {
+ Container.Ordered, Container.Sortable, ItemClickSource {
private static final int CELL_KEY = 0;
@@ -306,6 +310,8 @@ public class Table extends AbstractSelect implements Action.Container,
*/
private CellStyleGenerator cellStyleGenerator = null;
+ private int clickListenerCount;
+
/* Table constructors */
/**
@@ -364,7 +370,7 @@ public class Table extends AbstractSelect implements Action.Container,
*
- *
@@ -574,7 +574,7 @@ public class IOrderedLayout extends Panel implements Container,
* without letting root element to affect the calculation.
*
* @param offset
- * offsetWidth or offsetHeight
+ * offsetWidth or offsetHeight
*/
private int rootOffsetMeasure(String offset) {
// TODO This method must be optimized!
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IPanel.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IPanel.java
index 37fb6feca8..3493617722 100644
--- a/src/com/itmill/toolkit/terminal/gwt/client/ui/IPanel.java
+++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IPanel.java
@@ -302,8 +302,6 @@ public class IPanel extends SimplePanel implements Paintable,
// Restore content to flow
if (hasChildren) {
- ApplicationConnection.getConsole().log(
- "positioning:" + origPositioning);
DOM.setStyleAttribute(contentEl, "position", origPositioning);
}
// restore scroll position
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IScrollTable.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IScrollTable.java
index 25209a1431..6dab67ccd6 100644
--- a/src/com/itmill/toolkit/terminal/gwt/client/ui/IScrollTable.java
+++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IScrollTable.java
@@ -27,6 +27,7 @@ import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.Widget;
import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
import com.itmill.toolkit.terminal.gwt.client.ContainerResizedListener;
+import com.itmill.toolkit.terminal.gwt.client.MouseEventDetails;
import com.itmill.toolkit.terminal.gwt.client.Paintable;
import com.itmill.toolkit.terminal.gwt.client.UIDL;
import com.itmill.toolkit.terminal.gwt.client.Util;
@@ -128,6 +129,7 @@ public class IScrollTable extends Composite implements Table, ScrollListener,
* for container element. Then this value is used as a fallback.
*/
private int oldAvailPixels;
+ private boolean emitClickEvents;
public IScrollTable() {
@@ -154,6 +156,7 @@ public class IScrollTable extends Composite implements Table, ScrollListener,
this.client = client;
paintableId = uidl.getStringAttribute("id");
immediate = uidl.getBooleanAttribute("immediate");
+ emitClickEvents = uidl.getBooleanAttribute("listenClicks");
final int newTotalRows = uidl.getIntAttribute("totalrows");
if (newTotalRows != totalRows) {
if (tBody != null) {
@@ -1942,7 +1945,7 @@ public class IScrollTable extends Composite implements Table, ScrollListener,
private IScrollTableRow(int rowKey) {
this.rowKey = rowKey;
setElement(DOM.createElement("tr"));
- DOM.sinkEvents(getElement(), Event.ONCLICK);
+ DOM.sinkEvents(getElement(), Event.ONCLICK | Event.ONDBLCLICK);
attachContextMenuEvent(getElement());
}
@@ -2084,26 +2087,55 @@ public class IScrollTable extends Composite implements Table, ScrollListener,
return false;
}
+ private void handleClickEvent(Event event) {
+ if (emitClickEvents) {
+ boolean dbl = DOM.eventGetType(event) == Event.ONDBLCLICK;
+ final Element tdOrTr = DOM.getParent(DOM
+ .eventGetTarget(event));
+ client.updateVariable(paintableId, "clickedKey", ""
+ + rowKey, false);
+ if (DOM.compare(getElement(), DOM.getParent(tdOrTr))) {
+ int childIndex = DOM
+ .getChildIndex(getElement(), tdOrTr);
+ String colKey = null;
+ colKey = tHead.getHeaderCell(childIndex).getColKey();
+ client.updateVariable(paintableId, "clickedColKey",
+ colKey, false);
+ }
+ MouseEventDetails details = new MouseEventDetails(event);
+ client
+ .updateVariable(
+ paintableId,
+ "clickEvent",
+ details.toString(),
+ !(!dbl
+ && selectMode > Table.SELECT_MODE_NONE && immediate));
+ }
+ }
+
/*
* React on click that occur on content cells only
*/
public void onBrowserEvent(Event event) {
- switch (DOM.eventGetType(event)) {
- case Event.ONCLICK:
- final Element tdOrTr = DOM.getParent(DOM
- .eventGetTarget(event));
- if (DOM.compare(getElement(), tdOrTr)
- || DOM.compare(getElement(), DOM.getParent(tdOrTr))) {
+ final Element tdOrTr = DOM.getParent(DOM.eventGetTarget(event));
+ if (DOM.compare(getElement(), tdOrTr)
+ || DOM.compare(getElement(), DOM.getParent(tdOrTr))) {
+ switch (DOM.eventGetType(event)) {
+ case Event.ONCLICK:
+ handleClickEvent(event);
if (selectMode > Table.SELECT_MODE_NONE) {
toggleSelection();
client.updateVariable(paintableId, "selected",
selectedRowKeys.toArray(), immediate);
}
- }
- break;
+ break;
+ case Event.ONDBLCLICK:
+ handleClickEvent(event);
+ break;
- default:
- break;
+ default:
+ break;
+ }
}
super.onBrowserEvent(event);
}
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/ITree.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/ITree.java
index 4615d3990f..08f3930799 100644
--- a/src/com/itmill/toolkit/terminal/gwt/client/ui/ITree.java
+++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/ITree.java
@@ -16,6 +16,7 @@ import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
+import com.itmill.toolkit.terminal.gwt.client.MouseEventDetails;
import com.itmill.toolkit.terminal.gwt.client.Paintable;
import com.itmill.toolkit.terminal.gwt.client.UIDL;
import com.itmill.toolkit.terminal.gwt.client.Util;
@@ -49,6 +50,8 @@ public class ITree extends FlowPanel implements Paintable {
private boolean readonly;
+ private boolean emitClickEvents;
+
public ITree() {
super();
setStyleName(CLASSNAME);
@@ -97,6 +100,7 @@ public class ITree extends FlowPanel implements Paintable {
disabled = uidl.getBooleanAttribute("disabled");
readonly = uidl.getBooleanAttribute("readonly");
+ emitClickEvents = uidl.getBooleanAttribute("listenClicks");
isNullSelectionAllowed = uidl.getBooleanAttribute("nullselect");
@@ -189,7 +193,7 @@ public class ITree extends FlowPanel implements Paintable {
public TreeNode() {
constructDom();
- sinkEvents(Event.ONCLICK);
+ sinkEvents(Event.ONCLICK | Event.ONDBLCLICK | Event.ONMOUSEUP);
}
public void onBrowserEvent(Event event) {
@@ -197,14 +201,19 @@ public class ITree extends FlowPanel implements Paintable {
if (disabled) {
return;
}
- if (DOM.eventGetType(event) == Event.ONCLICK) {
- final Element target = DOM.eventGetTarget(event);
+ final int type = DOM.eventGetType(event);
+ final Element target = DOM.eventGetTarget(event);
+ if (emitClickEvents && DOM.compare(target, nodeCaptionSpan)
+ && (type == Event.ONDBLCLICK || type == Event.ONMOUSEUP)) {
+ fireClick(event);
+ }
+ if (type == Event.ONCLICK) {
if (DOM.compare(getElement(), target)
|| DOM.compare(ie6compatnode, target)) {
// state change
toggleState();
} else if (!readonly && DOM.compare(target, nodeCaptionSpan)) {
- // caption click = selection change
+ // caption click = selection change && possible click event
toggleSelection();
}
DOM.eventCancelBubble(event, true);
@@ -215,6 +224,13 @@ public class ITree extends FlowPanel implements Paintable {
}
+ private void fireClick(Event evt) {
+ MouseEventDetails details = new MouseEventDetails(evt);
+ client.updateVariable(paintableId, "clickedKey", key, false);
+ client.updateVariable(paintableId, "clickEvent",
+ details.toString(), !(selectable && immediate));
+ }
+
private void toggleSelection() {
if (selectable) {
ITree.this.setSelected(this, !isSelected());
diff --git a/src/com/itmill/toolkit/tests/tickets/Ticket2009.java b/src/com/itmill/toolkit/tests/tickets/Ticket2009.java
new file mode 100644
index 0000000000..f9eebb02b7
--- /dev/null
+++ b/src/com/itmill/toolkit/tests/tickets/Ticket2009.java
@@ -0,0 +1,125 @@
+package com.itmill.toolkit.tests.tickets;
+
+import com.itmill.toolkit.data.Container;
+import com.itmill.toolkit.event.ItemClickEvent;
+import com.itmill.toolkit.tests.TestForTablesInitialColumnWidthLogicRendering;
+import com.itmill.toolkit.ui.Button;
+import com.itmill.toolkit.ui.Label;
+import com.itmill.toolkit.ui.OrderedLayout;
+import com.itmill.toolkit.ui.Panel;
+import com.itmill.toolkit.ui.Table;
+import com.itmill.toolkit.ui.TextField;
+import com.itmill.toolkit.ui.Tree;
+import com.itmill.toolkit.ui.Window;
+import com.itmill.toolkit.ui.Button.ClickEvent;
+
+public class Ticket2009 extends com.itmill.toolkit.Application {
+
+ TextField f = new TextField();
+
+ public void init() {
+ final Window main = new Window(getClass().getName().substring(
+ getClass().getName().lastIndexOf(".") + 1));
+ setMainWindow(main);
+
+ OrderedLayout ol = new OrderedLayout(
+ OrderedLayout.ORIENTATION_HORIZONTAL);
+ main.setLayout(ol);
+ ol.setSizeFull();
+
+ Panel p = new Panel("Tree test");
+ p.setSizeFull();
+
+ Tree t = new Tree();
+
+ t.addItem("Foo");
+ t.addItem("Bar");
+
+ final OrderedLayout events = new OrderedLayout();
+
+ t.addListener(new ItemClickEvent.ItemClickListener() {
+ public void itemClick(ItemClickEvent event) {
+ events.addComponent(new Label(new Label("Click:"
+ + (event.isDoubleClick() ? "double" : "single")
+ + " button:" + event.getButton() + " propertyId:"
+ + event.getPropertyId() + " itemID:"
+ + event.getItemId() + " item:" + event.getItem())));
+
+ }
+ });
+
+ main.addComponent(p);
+ p.addComponent(t);
+ p.addComponent(events);
+
+ Panel p2 = new Panel("Table test (try dbl click also)");
+ p2.setSizeFull();
+
+ final OrderedLayout events2 = new OrderedLayout();
+ Table table = TestForTablesInitialColumnWidthLogicRendering
+ .getTestTable(5, 100);
+ table.setRowHeaderMode(Table.ROW_HEADER_MODE_ID);
+ table.addListener(new ItemClickEvent.ItemClickListener() {
+ public void itemClick(ItemClickEvent event) {
+ events2.addComponent(new Label("Click:"
+ + (event.isDoubleClick() ? "double" : "single")
+ + " button:" + event.getButton() + " propertyId:"
+ + event.getPropertyId() + " itemID:"
+ + event.getItemId() + " item:" + event.getItem()));
+ if (event.isDoubleClick()) {
+ new PropertyEditor(event);
+ }
+
+ }
+ });
+ p2.addComponent(table);
+ p2.addComponent(events2);
+
+ main.addComponent(p2);
+
+ }
+
+ class PropertyEditor extends Window {
+
+ private static final int W = 300;
+ private static final int H = 150;
+
+ private Container c;
+ private Object itemid;
+ private Object propertyid;
+
+ TextField editor = new TextField();
+ Button done = new Button("Done");
+
+ PropertyEditor(ItemClickEvent event) {
+ c = (Container) event.getSource();
+
+ propertyid = event.getPropertyId();
+ itemid = event.getItemId();
+
+ setCaption("Editing " + itemid + " : " + propertyid);
+
+ editor.setPropertyDataSource(c.getContainerProperty(itemid,
+ propertyid));
+ addComponent(editor);
+ addComponent(done);
+
+ setWidth(W);
+ setHeight(H);
+
+ setPositionX(event.getClientX() - W / 2);
+ setPositionY(event.getClientY() - H / 2);
+
+ getMainWindow().addWindow(this);
+
+ done.addListener(new Button.ClickListener() {
+ public void buttonClick(ClickEvent event) {
+ getMainWindow().removeWindow(PropertyEditor.this);
+ }
+ });
+
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/com/itmill/toolkit/ui/Table.java b/src/com/itmill/toolkit/ui/Table.java
index a8b660554f..1a5fb10a67 100644
--- a/src/com/itmill/toolkit/ui/Table.java
+++ b/src/com/itmill/toolkit/ui/Table.java
@@ -21,10 +21,14 @@ import com.itmill.toolkit.data.Property;
import com.itmill.toolkit.data.util.ContainerOrderedWrapper;
import com.itmill.toolkit.data.util.IndexedContainer;
import com.itmill.toolkit.event.Action;
+import com.itmill.toolkit.event.ItemClickEvent;
+import com.itmill.toolkit.event.ItemClickEvent.ItemClickListener;
+import com.itmill.toolkit.event.ItemClickEvent.ItemClickSource;
import com.itmill.toolkit.terminal.KeyMapper;
import com.itmill.toolkit.terminal.PaintException;
import com.itmill.toolkit.terminal.PaintTarget;
import com.itmill.toolkit.terminal.Resource;
+import com.itmill.toolkit.terminal.gwt.client.MouseEventDetails;
/**
*
getVisibleColumns
method.
+ * the Array of column headers that match the
+ * getVisibleColumns
method.
*/
public void setColumnHeaders(String[] columnHeaders) {
@@ -521,8 +527,8 @@ public class Table extends AbstractSelect implements Action.Container,
*
*
* @param columnIcons
- * the Array of icons that match the
- * getVisibleColumns
.
+ * the Array of icons that match the
+ * getVisibleColumns
.
*/
public void setColumnIcons(Resource[] columnIcons) {
@@ -548,8 +554,8 @@ public class Table extends AbstractSelect implements Action.Container,
*
*
* The items in the array must match the properties identified by
- * getVisibleColumns()
. The possible values for the alignments
- * include:
+ * getVisibleColumns()
. The possible values for the
+ * alignments include:
*
ALIGN_LEFT
: Left alignmentALIGN_CENTER
: Centered
* The items in the array must match the properties identified by
- * getVisibleColumns()
. The possible values for the alignments
- * include:
+ * getVisibleColumns()
. The possible values for the
+ * alignments include:
*
ALIGN_LEFT
: Left alignmentALIGN_CENTER
: CenteredtoString()
is used as row caption.
* ROW_HEADER_MODE_PROPERTY
: Property set with
* setItemCaptionPropertyId()
is used as row header.
- * ROW_HEADER_MODE_EXPLICIT_DEFAULTS_ID
: Items Id-objects
- * toString()
is used as row header. If caption is explicitly
- * specified, it overrides the id-caption.
+ * ROW_HEADER_MODE_EXPLICIT_DEFAULTS_ID
: Items
+ * Id-objects toString()
is used as row header. If caption is
+ * explicitly specified, it overrides the id-caption.
* ROW_HEADER_MODE_EXPLICIT
: The row headers must be
* explicitly specified.ROW_HEADER_MODE_INDEX
: The index of the item is used as
- * row caption. The index mode can only be used with the containers
+ * ROW_HEADER_MODE_INDEX
: The index of the item is used
+ * as row caption. The index mode can only be used with the containers
* implementing Container.Indexed
interface.ROW_HEADER_MODE_HIDDEN
*
*
* @param mode
- * the One of the modes listed above.
+ * the One of the modes listed above.
*/
public void setRowHeaderMode(int mode) {
if (ROW_HEADER_MODE_HIDDEN == mode) {
@@ -1435,13 +1441,13 @@ public class Table extends AbstractSelect implements Action.Container,
* columns) with given values.
*
* @param cells
- * the Object array that is used for filling the visible cells
- * new row. The types must be settable to visible column property
- * types.
+ * the Object array that is used for filling the visible
+ * cells new row. The types must be settable to visible
+ * column property types.
* @param itemId
- * the Id the new row. If null, a new id is automatically
- * assigned. If given, the table cant already have a item with
- * given id.
+ * the Id the new row. If null, a new id is automatically
+ * assigned. If given, the table cant already have a item
+ * with given id.
* @return Returns item id for the new row. Returns null if operation fails.
*/
public Object addItem(Object[] cells, Object itemId)
@@ -1704,7 +1710,38 @@ public class Table extends AbstractSelect implements Action.Container,
}
}
- enableContentRefreshing(clientNeedsContentRefresh);
+ // handle clicks before content refresh if content is refreshed anyway
+ if (clientNeedsContentRefresh) {
+ handleClickEvent(variables);
+ enableContentRefreshing(clientNeedsContentRefresh);
+ } else {
+ enableContentRefreshing(clientNeedsContentRefresh);
+ handleClickEvent(variables);
+ }
+ }
+
+ /**
+ * Handles click event
+ *
+ * @param variables
+ */
+ private void handleClickEvent(Map variables) {
+ if (clickListenerCount > 0) {
+ if (variables.containsKey("clickEvent")) {
+ String key = (String) variables.get("clickedKey");
+ Object itemId = itemIdMapper.get(key);
+ Object propertyId = null;
+ String colkey = (String) variables.get("clickedColKey");
+ // click is not necessary on a property
+ if (colkey != null) {
+ propertyId = columnIdMap.get(colkey);
+ }
+ MouseEventDetails evt = MouseEventDetails
+ .deSerialize((String) variables.get("clickEvent"));
+ fireEvent(new ItemClickEvent(this, getItem(itemId), itemId,
+ propertyId, evt));
+ }
+ }
}
/**
@@ -1724,7 +1761,7 @@ public class Table extends AbstractSelect implements Action.Container,
* Go to mode where content content refreshing has effect.
*
* @param refreshContent
- * true if content refresh needs to be done
+ * true if content refresh needs to be done
*/
protected void enableContentRefreshing(boolean refreshContent) {
isContentRefreshesEnabled = true;
@@ -1736,9 +1773,8 @@ public class Table extends AbstractSelect implements Action.Container,
/*
* (non-Javadoc)
*
- * @see
- * com.itmill.toolkit.ui.AbstractSelect#paintContent(com.itmill.toolkit.
- * terminal.PaintTarget)
+ * @see com.itmill.toolkit.ui.AbstractSelect#paintContent(com.itmill.toolkit.
+ * terminal.PaintTarget)
*/
public void paintContent(PaintTarget target) throws PaintException {
@@ -1800,6 +1836,11 @@ public class Table extends AbstractSelect implements Action.Container,
} else {
target.addAttribute("selectmode", "none");
}
+
+ if (clickListenerCount > 0) {
+ target.addAttribute("listenClicks", true);
+ }
+
target.addAttribute("cols", cols);
target.addAttribute("rows", rows);
@@ -2106,11 +2147,11 @@ public class Table extends AbstractSelect implements Action.Container,
* the value representation.
*
* @param rowId
- * the Id of the row (same as item Id).
+ * the Id of the row (same as item Id).
* @param colId
- * the Id of the column.
+ * the Id of the column.
* @param property
- * the Property to be presented.
+ * the Property to be presented.
* @return Object Either formatted value or Component for field.
* @see #setFieldFactory(FieldFactory)
*/
@@ -2133,11 +2174,11 @@ public class Table extends AbstractSelect implements Action.Container,
* and return a empty string for null properties.
*
* @param rowId
- * the Id of the row (same as item Id).
+ * the Id of the row (same as item Id).
* @param colId
- * the Id of the column.
+ * the Id of the column.
* @param property
- * the Property to be formatted.
+ * the Property to be formatted.
* @return the String representation of property and its value.
* @since 3.1
*/
@@ -2305,11 +2346,11 @@ public class Table extends AbstractSelect implements Action.Container,
* Adds a new property to the table and show it as a visible column.
*
* @param propertyId
- * the Id of the proprty.
+ * the Id of the proprty.
* @param type
- * the class of the property.
+ * the class of the property.
* @param defaultValue
- * the default value given for all existing items.
+ * the default value given for all existing items.
* @see com.itmill.toolkit.data.Container#addContainerProperty(Object,
* Class, Object)
*/
@@ -2339,21 +2380,21 @@ public class Table extends AbstractSelect implements Action.Container,
* Adds a new property to the table and show it as a visible column.
*
* @param propertyId
- * the Id of the proprty
+ * the Id of the proprty
* @param type
- * the class of the property
+ * the class of the property
* @param defaultValue
- * the default value given for all existing items
+ * the default value given for all existing items
* @param columnHeader
- * the Explicit header of the column. If explicit header is not
- * needed, this should be set null.
+ * the Explicit header of the column. If explicit header is
+ * not needed, this should be set null.
* @param columnIcon
- * the Icon of the column. If icon is not needed, this should be
- * set null.
+ * the Icon of the column. If icon is not needed, this should
+ * be set null.
* @param columnAlignment
- * the Alignment of the column. Null implies align left.
+ * the Alignment of the column. Null implies align left.
* @throws UnsupportedOperationException
- * if the operation is not supported.
+ * if the operation is not supported.
* @see com.itmill.toolkit.data.Container#addContainerProperty(Object,
* Class, Object)
*/
@@ -2388,9 +2429,9 @@ public class Table extends AbstractSelect implements Action.Container,
*
*
* @param id
- * the id of the column to be added
+ * the id of the column to be added
* @param generatedColumn
- * the {@link ColumnGenerator} to use for this column
+ * the {@link ColumnGenerator} to use for this column
*/
public void addGeneratedColumn(Object id, ColumnGenerator generatedColumn) {
if (generatedColumn == null) {
@@ -2412,7 +2453,7 @@ public class Table extends AbstractSelect implements Action.Container,
* Removes a generated column previously added with addGeneratedColumn.
*
* @param id
- * id of the generated column to remove
+ * id of the generated column to remove
* @return true if the column could be removed (existed in the Table)
*/
public boolean removeGeneratedColumn(Object id) {
@@ -2487,7 +2528,7 @@ public class Table extends AbstractSelect implements Action.Container,
* Adding new items is not supported.
*
* @throws UnsupportedOperationException
- * if set to true.
+ * if set to true.
* @see com.itmill.toolkit.ui.Select#setNewItemsAllowed(boolean)
*/
public void setNewItemsAllowed(boolean allowNewOptions)
@@ -2501,7 +2542,7 @@ public class Table extends AbstractSelect implements Action.Container,
* Focusing to this component is not supported.
*
* @throws UnsupportedOperationException
- * if invoked.
+ * if invoked.
* @see com.itmill.toolkit.ui.AbstractField#focus()
*/
public void focus() throws UnsupportedOperationException {
@@ -2617,7 +2658,7 @@ public class Table extends AbstractSelect implements Action.Container,
* BaseFieldFactory is used.
*
* @param fieldFactory
- * the field factory to set.
+ * the field factory to set.
* @see #isEditable
* @see BaseFieldFactory
*
@@ -2660,7 +2701,7 @@ public class Table extends AbstractSelect implements Action.Container,
* property to true.
*
* @param editable
- * true if table should be editable by user.
+ * true if table should be editable by user.
* @see Field
* @see FieldFactory
*
@@ -2677,8 +2718,8 @@ public class Table extends AbstractSelect implements Action.Container,
* Sorts the table.
*
* @throws UnsupportedOperationException
- * if the container data source does not implement
- * Container.Sortable
+ * if the container data source does not implement
+ * Container.Sortable
* @see com.itmill.toolkit.data.Container.Sortable#sort(java.lang.Object[],
* boolean[])
*
@@ -2703,8 +2744,8 @@ public class Table extends AbstractSelect implements Action.Container,
* Sorts the table by currently selected sorting column.
*
* @throws UnsupportedOperationException
- * if the container data source does not implement
- * Container.Sortable
+ * if the container data source does not implement
+ * Container.Sortable
*/
public void sort() {
if (getSortContainerPropertyId() == null) {
@@ -2741,7 +2782,7 @@ public class Table extends AbstractSelect implements Action.Container,
* Sets the currently sorted column property id.
*
* @param propertyId
- * the Container property id of the currently sorted column.
+ * the Container property id of the currently sorted column.
*/
public void setSortContainerPropertyId(Object propertyId) {
setSortContainerPropertyId(propertyId, true);
@@ -2771,7 +2812,8 @@ public class Table extends AbstractSelect implements Action.Container,
/**
* Is the table currently sorted in ascending order.
*
- * @return true
if ascending, false
if descending.
+ * @return true
if ascending, false
if
+ * descending.
*/
public boolean isSortAscending() {
return sortAscending;
@@ -2781,8 +2823,8 @@ public class Table extends AbstractSelect implements Action.Container,
* Sets the table in ascending order.
*
* @param ascending
- * true
if ascending, false
if
- * descending.
+ * true
if ascending, false
if
+ * descending.
*/
public void setSortAscending(boolean ascending) {
setSortAscending(ascending, true);
@@ -2825,7 +2867,7 @@ public class Table extends AbstractSelect implements Action.Container,
* columns are given even in the case where datasource would support this.
*
* @param sortDisabled
- * True iff sorting is disabled.
+ * True iff sorting is disabled.
*/
public void setSortDisabled(boolean sortDisabled) {
if (this.sortDisabled != sortDisabled) {
@@ -2870,12 +2912,13 @@ public class Table extends AbstractSelect implements Action.Container,
* generated.
*
* @param source
- * the source Table
+ * the source Table
* @param itemId
- * the itemId (aka rowId) for the of the cell to be generated
+ * the itemId (aka rowId) for the of the cell to be
+ * generated
* @param columnId
- * the id for the generated column (as specified in
- * addGeneratedColumn)
+ * the id for the generated column (as specified in
+ * addGeneratedColumn)
* @return
*/
public abstract Component generateCell(Table source, Object itemId,
@@ -2886,7 +2929,7 @@ public class Table extends AbstractSelect implements Action.Container,
* Set cell style generator for Table.
*
* @param cellStyleGenerator
- * New cell style generator or null to remove generator.
+ * New cell style generator or null to remove generator.
*/
public void setCellStyleGenerator(CellStyleGenerator cellStyleGenerator) {
this.cellStyleGenerator = cellStyleGenerator;
@@ -2914,13 +2957,36 @@ public class Table extends AbstractSelect implements Action.Container,
* Called by Table when a cell (and row) is painted.
*
* @param itemId
- * The itemId of the painted cell
+ * The itemId of the painted cell
* @param propertyId
- * The propertyId of the cell, null when getting row style
+ * The propertyId of the cell, null when getting row
+ * style
* @return The style name to add to this cell or row. (the CSS class
* name will be i-table-cell-content-[style name], or
* i-table-row-[style name] for rows)
*/
public abstract String getStyle(Object itemId, Object propertyId);
}
+
+ public void addListener(ItemClickListener listener) {
+ addListener(ItemClickEvent.class, listener,
+ ItemClickEvent.ITEM_CLICK_METHOD);
+ clickListenerCount++;
+ // repaint needed only if click listening became necessary
+ if (clickListenerCount == 1) {
+ requestRepaint();
+ }
+
+ }
+
+ public void removeListener(ItemClickListener listener) {
+ removeListener(ItemClickEvent.class, listener,
+ ItemClickEvent.ITEM_CLICK_METHOD);
+ clickListenerCount++;
+ // repaint needed only if click listening is not needed in client
+ // anymore
+ if (clickListenerCount == 0) {
+ requestRepaint();
+ }
+ }
}
diff --git a/src/com/itmill/toolkit/ui/Tree.java b/src/com/itmill/toolkit/ui/Tree.java
index 67383ef51f..c6d07ebe65 100644
--- a/src/com/itmill/toolkit/ui/Tree.java
+++ b/src/com/itmill/toolkit/ui/Tree.java
@@ -21,10 +21,14 @@ import com.itmill.toolkit.data.Container;
import com.itmill.toolkit.data.util.ContainerHierarchicalWrapper;
import com.itmill.toolkit.data.util.IndexedContainer;
import com.itmill.toolkit.event.Action;
+import com.itmill.toolkit.event.ItemClickEvent;
+import com.itmill.toolkit.event.ItemClickEvent.ItemClickListener;
+import com.itmill.toolkit.event.ItemClickEvent.ItemClickSource;
import com.itmill.toolkit.terminal.KeyMapper;
import com.itmill.toolkit.terminal.PaintException;
import com.itmill.toolkit.terminal.PaintTarget;
import com.itmill.toolkit.terminal.Resource;
+import com.itmill.toolkit.terminal.gwt.client.MouseEventDetails;
/**
* MenuTree component. MenuTree can be used to select an item (or multiple
@@ -36,7 +40,7 @@ import com.itmill.toolkit.terminal.Resource;
* @since 3.0
*/
public class Tree extends AbstractSelect implements Container.Hierarchical,
- Action.Container {
+ Action.Container, ItemClickSource {
/* Static members */
@@ -327,6 +331,15 @@ public class Tree extends AbstractSelect implements Container.Hierarchical,
*/
public void changeVariables(Object source, Map variables) {
+ if (clickListenerCount > 0 && variables.containsKey("clickedKey")) {
+ String key = (String) variables.get("clickedKey");
+
+ Object id = itemIdMapper.get(key);
+ MouseEventDetails details = MouseEventDetails.deSerialize((String) variables
+ .get("clickEvent"));
+ fireEvent(new ItemClickEvent(this, getItem(id), id, null, details));
+ }
+
if (!isSelectable() && variables.containsKey("selected")) {
// Not-selectable is a special case, AbstractSelect does not support
// TODO could be optimized.
@@ -418,6 +431,10 @@ public class Tree extends AbstractSelect implements Container.Hierarchical,
target.addAttribute("nullselect", true);
}
+ if (clickListenerCount > 0) {
+ target.addAttribute("listenClicks", true);
+ }
+
}
// Initialize variables
@@ -996,4 +1013,27 @@ public class Tree extends AbstractSelect implements Container.Hierarchical,
}
}
+ private int clickListenerCount = 0;
+
+ public void addListener(ItemClickListener listener) {
+ addListener(ItemClickEvent.class, listener,
+ ItemClickEvent.ITEM_CLICK_METHOD);
+ clickListenerCount++;
+ // repaint needed only if click listening became necessary
+ if (clickListenerCount == 1) {
+ requestRepaint();
+ }
+ }
+
+ public void removeListener(ItemClickListener listener) {
+ removeListener(ItemClickEvent.class, listener,
+ ItemClickEvent.ITEM_CLICK_METHOD);
+ clickListenerCount++;
+ // repaint needed only if click listening is not needed in client
+ // anymore
+ if (clickListenerCount == 0) {
+ requestRepaint();
+ }
+ }
+
}
--
2.39.5