I extends a gwt celltable to create a custom celltable, i register the sinkevents ie onmouseover/onmouseout.
when you hover on the row of the table the row data is populated on the hover wiget(custom hover popup panel).
its works as it supose to do on development mode but once deployed on tomcat when you move the mouse over different rows on the celltable it
does not update the hover data on the popup panel unless you click away from the table(loose focus) and the hover again on the row.
public class MyCellTable<T> extends CellTable<T> {
private Tooltip popup = new Tooltip();
private List<String> tooltipHiddenColumn = new ArrayList<String>();
private boolean showTooltip;
public MyCellTable() {
super();
sinkEvents(Event.ONMOUSEOVER | Event.ONMOUSEOUT);
}
#Override
public void onBrowserEvent2(Event event) {
super.onBrowserEvent2(event);
if (isShowTooltip()) {
switch (DOM.eventGetType(event)) {
case Event.ONMOUSEOUT: {
popup.hide(true);
break;
}
case Event.ONMOUSEOVER: {
popup.setAutoHideEnabled(true);
showToolTip(event);
break;
}
}
}
}
private void showToolTip(final Event event) {
EventTarget eventTarget = event.getEventTarget();
if (!Element.is(eventTarget)) {
return;
}
final Element target = event.getEventTarget().cast();
// Find the cell where the event occurred.
TableCellElement tableCell = findNearestParentCell(target);
if (tableCell == null) {
return;
}
Element trElem = tableCell.getParentElement();
if (trElem == null) {
return;
}
TableRowElement tr = TableRowElement.as(trElem);
Element sectionElem = tr.getParentElement();
if (sectionElem == null) {
return;
}
TableSectionElement section = TableSectionElement.as(sectionElem);
if (section == getTableHeadElement()) {
return;
}
NodeList<TableCellElement> cellElements = tr.getCells().cast();
NodeList<TableCellElement> headers = getTableHeadElement().getRows().getItem(0).getCells().cast();
popup.getGrid().clear(true);
popup.getGrid().resizeRows(cellElements.getLength());
for (int i = 0; i < cellElements.getLength(); i++) {
if (getTooltipHiddenColumn().indexOf(headers.getItem(i).getInnerHTML()) == -1) {
TableCellElement tst = TableCellElement.as(cellElements.getItem(i));
popup.getGrid().setHTML(i, 0, headers.getItem(i).getInnerHTML());
popup.getGrid().setHTML(i, 1, tst.getInnerHTML());
}
}
// Here the constant values are used to give some gap between mouse pointer and popup panel
popup.setPopupPositionAndShow(new PopupPanel.PositionCallback() {
public void setPosition(int offsetWidth, int offsetHeight) {
int left = event.getClientX() + 5;
int top = event.getClientY() + 5;
if ((offsetHeight + top + 20) > Window.getClientHeight()) {
top = top - offsetHeight - 10;
}
popup.setPopupPosition(left, top);
}
});
popup.show();
}
public ArrayList<ReorderColumnsDetails> getColumnsHeaders(int index){
ArrayList<ReorderColumnsDetails> column = new ArrayList<ReorderColumnsDetails>();
NodeList<TableCellElement> headers = getTableHeadElement().getRows().getItem(0).getCells().cast();
for (int i = 0; i < index; i++) {
ReorderColumnsDetails clm = new ReorderColumnsDetails();
clm.setHearder(headers.getItem(i).getInnerHTML().toString());
clm.setItemIndex(i);
column.add(clm);
}
return column;
}
private TableCellElement findNearestParentCell(Element elem) {
while ((elem != null) && (elem != getElement())) {
String tagName = elem.getTagName();
if ("td".equalsIgnoreCase(tagName) || "th".equalsIgnoreCase(tagName)) {
return elem.cast();
}
elem = elem.getParentElement();
}
return null;
}
/**
* Specify Name of the column's which is not to shown in the Tooltip
*/
public List<String> getTooltipHiddenColumn() {
return tooltipHiddenColumn;
}
/**
* Set title to tooltip
*
* #param title
*/
public void setTooltipTitle(String title) {
popup.setHTML(title);
}
public boolean isShowTooltip() {
return showTooltip;
}
public void setShowTooltip(boolean showTooltip) {
this.showTooltip = showTooltip;
}
}
Related
I am trying to create a table with ComboBoxCellEditor column. When I set value that time below exception is coming.
import org.eclipse.jface.util.Policy;
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
/............/
public class Test {
public static void main(String[] args) {
Shell shell = new Shell();
shell.setText("TableViewer Example");
GridLayout layout = new GridLayout();
shell.setLayout(layout);
Composite composite = new Composite(shell, SWT.NONE);
composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
composite.setLayout(new GridLayout(1, false));
Table testTable = new Table(composite, SWT.BORDER);
testTable.setLinesVisible(true);
testTable.setHeaderVisible(true);
GridData tableData = new GridData(SWT.FILL, SWT.FILL, true, false);
tableData.heightHint = 300;
testTable.setLayoutData(tableData);
TableViewerColumn columnViewer = null;
String[] columnNames = { "Name", "Laptops" };
TableViewer testTableViewer = new TableViewer(testTable);
for (int i = 0; i < columnNames.length; i++) {
columnViewer = new TableViewerColumn(testTableViewer, SWT.LEFT);
columnViewer.getColumn().setText(columnNames[i]);
if (columnNames[i].equals("Name")) {
columnViewer.getColumn().setWidth(200);
} else if (columnNames[i].equals("Laptops")) {
columnViewer.getColumn().setWidth(300);
}
columnViewer.getColumn().setResizable(true);
columnViewer.getColumn().setMoveable(true);
columnViewer.setLabelProvider(new TestColumnLabelProvider(i));
}
testTableViewer.setContentProvider(new TestContentProvider());
testTableViewer.setColumnProperties(columnNames);
TestBean[] testBeans = new TestBean[5];
for (int i = 0; i < 5; i++) {
TestBean bean = new TestBean();
TableViewerColumn[] getTableViewerColumns =
getTableViewerColumns(testTableViewer);
for (int j = 0; j < getTableViewerColumns.length; j++) {
getTableViewerColumns[j].setEditingSupport(new
TestEditingSuport(testTableViewer, j, bean.getListOfLaptop));
}
bean.setName("Debasish" + i);
bean.setLaptop(bean.getListOfLaptop[i]);
testBeans[i] = bean;
}
testTableViewer.setInput(testBeans);
shell.open();
Display display = shell.getDisplay();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
}
public static TableViewerColumn[] getTableViewerColumns(TableViewer
tableViewer) {
TableColumn[] columns = tableViewer.getTable().getColumns();
TableViewerColumn[] viewerColumns = new TableViewerColumn[columns.length];
for (int i = 0; i < columns.length; i++) {
TableColumn tableColumn = columns[i];
viewerColumns[i] = (TableViewerColumn) tableColumn.getData(Policy.JFACE +
".columnViewer");
}
return viewerColumns;
}
}
/............./
class TestBean {
private String name;
private String laptop;
public String[] getListOfLaptop = { "Acer", "HP", "Lenovo", "Dell", "Benq"
};
//getter and setter method
}
/..................../
class TestEditingSuport extends EditingSupport {
private int m_column;
private CellEditor m_editor;
public TestEditingSuport(ColumnViewer viewer, int column,
String[] listOfTestBean) {
super(viewer);
m_column = column;
// Create the correct editor based on the column index
switch (column) {
case 0:
case 1:
m_editor = new ComboBoxCellEditor(
((TableViewer) viewer).getTable(), listOfTestBean);
break;
default:
}
}
#Override
protected CellEditor getCellEditor(Object element) {
return m_editor;
}
#Override
protected boolean canEdit(Object element) {
return true;
}
#Override
protected Object getValue(Object element) {
TestBean bean = (TestBean) element;
Object value = null;
switch (m_column) {
case 0:
value = bean.getName();
break;
case 1:
value = bean.getLaptop();
break;
default:
}
return value;
}
#Override
protected void setValue(Object element, Object value) {
TestBean bean = (TestBean) element;
switch (m_column) {
case 0:
if (valueChanged(bean.getName(), (String) value)) {
bean.setName((String) value);
}
getViewer().update(bean, null);
break;
case 1:
int index = (Integer) value;
String laptop = bean.getListOfLaptop[index];
if (valueChanged(bean.getLaptop(), laptop)) {
bean.setLaptop(laptop);
}
getViewer().update(bean, null);
break;
default:
}
}
private boolean valueChanged(String previousValue, String currentValue) {
boolean changed = false;
if ((previousValue == null) && (currentValue != null)) {
changed = true;
} else if ((previousValue != null) && (currentValue != null) && (!previousValue.equals(currentValue))) {
changed = true;
}
return changed;
}
}
/............../
class TestContentProvider implements IStructuredContentProvider {
#Override
public Object[] getElements(Object inputElement) {
return (Object[]) inputElement;
}
}
/........................./
class TestColumnLabelProvider extends ColumnLabelProvider {
private int m_column;
public TestColumnLabelProvider(int column) {
this.m_column = column;
}
public String getText(Object element) {
String text = null;
if (element instanceof TestBean) {
TestBean testBean = (TestBean) element;
switch (m_column) {
case 0:
text = testBean.getName();
break;
case 1:
text = testBean.getLaptop();
break;
default:
}
}
return text;
}
}
/....................../
ComboCellEditor values are integer indexes in to the list of values you give it in the constructor.
Your getValue method of your EditingSupport class must return an Integer index in to the values list.
The setValue method of your EditingSupport class will be given an Integer containing the selected index.
Frineds,
I am using celltable and their is one column which I put in table header for select all record option and also I am using pager which showing max 15 record in one page. when I clicked on selectall option it will select all records which are present page no 2,3,4,.... in short all records get selected(if total records is 100 it's selected 100 records).so i want only select display page records not all...
ref code is -
final SelectionModel < GenericFirewallRule > selectionModel =
new MultiSelectionModel < GenericFirewallRule > ();
deleteRuleCellTable.setSelectionModel(selectionModel,DefaultSelectionEventManager. < GenericFirewallRule > createCheckboxManager());
// CheckboxCell cbForHeader = new CheckboxCell();
Column < GenericFirewallRule, Boolean > checkColumn = new Column < GenericFirewallRule, Boolean > (
new CheckboxCell()) {#Override
public Boolean getValue(GenericFirewallRule object) {
if(object == null || object.getRuleNumber() == null){
return null;
}else{
if (selectionModel.isSelected(object)) {
if (!ruleListForDelete.contains(object)) {
ruleListForDelete.add(object);
}
} else {
if (ruleListForDelete.contains(object)) {
ruleListForDelete.remove(object);
}
}
System.out.println("ruleListForDelete : " + ruleListForDelete);
return selectionModel.isSelected(object);
}
}
};
Please suggest me solutions....
You can do something like this:
selectAllHeader = new Header<Boolean>(new HeaderCheckbox()) {
#Override
public Boolean getValue() {
for (T item : getVisibleItems()) {
if (!getSelectionModel().isSelected(item)) {
return false;
}
}
return getVisibleItems().size() > 0;
}
};
selectAllHeader.setUpdater(new ValueUpdater<Boolean>() {
#Override
public void update(Boolean value) {
for (T object : getVisibleItems()) {
getSelectionModel().setSelected(object, value);
}
}
});
public class HeaderCheckbox extends CheckboxCell {
private final SafeHtml INPUT_CHECKED = SafeHtmlUtils.fromSafeConstant("<input type=\"checkbox\" tabindex=\"-1\" checked/>");
private final SafeHtml INPUT_UNCHECKED = SafeHtmlUtils.fromSafeConstant("<input type=\"checkbox\" tabindex=\"-1\"/>");
public HeaderCheckbox() {
}
#Override
public void render(Context context, Boolean value, SafeHtmlBuilder sb) {
if (value != null && value) {
sb.append(INPUT_CHECKED);
} else {
sb.append(INPUT_UNCHECKED);
}
}
}
I have a custom datagrid which is defined as follows
public class CustomDataGrid<T> extends DataGrid<T> {
private static final int PAGE_SIZE = 10;
public CustomDataGrid(ProvidesKey<T> keysProvider) {
super(PAGE_SIZE, keysProvider);
}
public CustomDataGrid() {
super(PAGE_SIZE);
}
public void redrawRow(int absRowIndex) {
int relRowIndex = absRowIndex - getPageStart();
checkRowBounds(relRowIndex);
setRowData(absRowIndex, Collections.singletonList(getVisibleItem(relRowIndex)));
}
}
I am using ui binder and in my xml file I have defined the elements as follows
<com:CustomDataGrid ui:field="commissionListDataGrid"></com:CustomDataGrid>
Now the custom datagrid is initialised as follows
#UiField
CustomDataGrid commissionListDataGrid;
private final Set<Long> showingFriends = new HashSet<Long>();
private Column<ServiceCategorywiseCommissionDetails, String> viewFriendsColumn;
private Column<ServiceCategorywiseCommissionDetails, String> serviceType;
public ZoneCommissionListView() {
commissionListDataGrid = new CustomDataGrid<ServiceCategorywiseCommissionDetails>(new ProvidesKey<ServiceCategorywiseCommissionDetails>() {
#Override
public Object getKey(ServiceCategorywiseCommissionDetails item) {
return item == null ? null : item.getId();
}
});
commissionListDataGrid.setWidth("100%");
commissionListDataGrid.setEmptyTableWidget(new Label("Empty data"));
commissionListDataGrid.setHeight("100%");
// commissionListLayoutPanel = new SimpleLayoutPanel();
initCommissionListDataGrid();
// commissionListLayoutPanel.add(commissionListDataGrid);
//RootLayoutPanel.get().add(commissionListLayoutPanel);
}
#Override
public Widget asWidget() {
return this.widget;
}
#Override
public void setUiHandlers(ZoneCommissionListUiHandlers uiHandlers) {
this.uiHandlers = uiHandlers;
}
public void initCommissionListDataGrid() {
// View friends.
SafeHtmlRenderer<String> anchorRenderer = new AbstractSafeHtmlRenderer<String>() {
#Override
public SafeHtml render(String object) {
SafeHtmlBuilder sb = new SafeHtmlBuilder();
sb.appendHtmlConstant("(").appendEscaped(object).appendHtmlConstant(")");
return sb.toSafeHtml();
}
};
viewFriendsColumn = new Column<ServiceCategorywiseCommissionDetails, String>(new ClickableTextCell(anchorRenderer)) {
#Override
public String getValue(ServiceCategorywiseCommissionDetails object) {
if (showingFriends.contains(object.getId())) {
return "-";
} else {
return "+";
}
}
};
viewFriendsColumn.setFieldUpdater(new FieldUpdater<ServiceCategorywiseCommissionDetails, String>() {
#Override
public void update(int index, ServiceCategorywiseCommissionDetails object, String value) {
if (showingFriends.contains(object.getId())) {
showingFriends.remove(object.getId());
} else {
showingFriends.add(object.getId());
}
// Redraw the modified row.
commissionListDataGrid.redrawRow(index);
}
});
// First name.
serviceType = new Column<ServiceCategorywiseCommissionDetails, String>(new TextCell()) {
#Override
public String getValue(ServiceCategorywiseCommissionDetails object) {
return object.getServiceType();
}
};
commissionListDataGrid.setTableBuilder(new CustomTableBuilder());
commissionListDataGrid.setHeaderBuilder(new CustomHeaderBuilder());
// commissionListDataGrid.setFooterBuilder(new CustomFooterBuilder());
// GWT.log("list size is " + ContactDatabase.get().getDataProvider().getList().size());
// commissionListDataGrid.setRowData(ContactDatabase.get().getDataProvider().getList());
// Button button = new Button();
// button.setText("hello");
// commissionListLayoutPanel.add(commissionListDataGrid);
this.widget = uiBinder.createAndBindUi(this);
}
private class CustomTableBuilder extends AbstractCellTableBuilder<ServiceCategorywiseCommissionDetails> {
private final String childCell = " ";
private final String rowStyle;
private final String selectedRowStyle;
private final String cellStyle;
private final String selectedCellStyle;
#SuppressWarnings("deprecation")
public CustomTableBuilder() {
super(commissionListDataGrid);
// Cache styles for faster access.
Style style = commissionListDataGrid.getResources().style();
rowStyle = style.evenRow();
selectedRowStyle = " " + style.selectedRow();
cellStyle = style.cell() + " " + style.evenRowCell();
selectedCellStyle = " " + style.selectedRowCell();
}
public void buildRowImpl(ServiceCategorywiseCommissionDetails rowValue, int absRowIndex) {
buildServiceTypeRow(rowValue, absRowIndex, false);
GWT.log("Inside build row impl");
// Display list of friends.
if (showingFriends.contains(rowValue.getId())) {
TableRowBuilder row = startRow();
TableCellBuilder th = row.startTH();
th.text("").endTH();
TableCellBuilder th2 = row.startTH();
th2.text("Service Name").endTH();
TableCellBuilder th3 = row.startTH();
th3.text("SuperZone Commission").endTH();
TableCellBuilder th4 = row.startTH();
th4.text("Zone Commission").endTH();
row.endTR();
List<ServiceCommissionDetails> friends = rowValue.getServiceCommissionDetails();
for (ServiceCommissionDetails friend : friends) {
buildServiceCommissionDetailRow(friend, absRowIndex, true);
}
}
}
#SuppressWarnings("deprecation")
private void buildServiceTypeRow(ServiceCategorywiseCommissionDetails rowValue, int absRowIndex, boolean isFriend) {
GWT.log("inside build service Type row");
SelectionModel<? super ServiceCategorywiseCommissionDetails> selectionModel = commissionListDataGrid.getSelectionModel();
boolean isSelected = (selectionModel == null || rowValue == null) ? false : selectionModel.isSelected(rowValue);
boolean isEven = absRowIndex % 2 == 0;
StringBuilder trClasses = new StringBuilder(rowStyle);
if (isSelected) {
trClasses.append(selectedRowStyle);
}
// Calculate the cell styles.
String cellStyles = cellStyle;
if (isSelected) {
cellStyles += selectedCellStyle;
}
if (isFriend) {
cellStyles += childCell;
}
TableRowBuilder row = startRow();
row.className(trClasses.toString());
/*
* Checkbox column.
*
* This table will uses a checkbox column for selection. Alternatively, you can call dataGrid.setSelectionEnabled(true) to
* enable mouse selection.
*/
TableCellBuilder td = row.startTD();
td.className(cellStyles);
td.style().outlineStyle(OutlineStyle.NONE).endStyle();
td.endTD();
/*
* View friends column.
*
* Displays a link to "show friends". When clicked, the list of friends is displayed below the contact.
*/
td = row.startTD();
td.className(cellStyles);
if (!isFriend) {
td.style().outlineStyle(OutlineStyle.NONE).endStyle();
renderCell(td, createContext(1), viewFriendsColumn, rowValue);
}
td.endTD();
// First name column.
td = row.startTD();
td.className(cellStyles);
td.style().outlineStyle(OutlineStyle.NONE).endStyle();
if (isFriend) {
td.text(rowValue.getServiceType());
} else {
renderCell(td, createContext(2), serviceType, rowValue);
}
td.endTD();
// Last name column.
row.endTR();
}
#SuppressWarnings("deprecation")
private void buildServiceCommissionDetailRow(ServiceCommissionDetails rowValue, int absRowIndex, boolean isFriend) {
GWT.log("inside build service commission detail row");
// Calculate the row styles.
// boolean isSelected = (selectionModel == null || rowValue == null)
// ? false : selectionModel.isSelected(rowValue);
// boolean isEven = absRowIndex % 2 == 0;
StringBuilder trClasses = new StringBuilder(rowStyle);
// if (isSelected) {
// trClasses.append(selectedRowStyle);
// }
// Calculate the cell styles.
String cellStyles = cellStyle;
// cellStyles += selectedCellStyle;
cellStyles += childCell;
TableRowBuilder row = startRow();
row.className(trClasses.toString());
/*
* Checkbox column.
*
* This table will uses a checkbox column for selection. Alternatively, you can call dataGrid.setSelectionEnabled(true) to
* enable mouse selection.
*/
TableCellBuilder td = row.startTD();
td.className(cellStyles);
td.style().outlineStyle(OutlineStyle.NONE).endStyle();
td.endTD();
/*
* View friends column.
*
* Displays a link to "show friends". When clicked, the list of friends is displayed below the contact.
*/
// First name column.
td = row.startTD();
td.className(cellStyles);
td.style().outlineStyle(OutlineStyle.NONE).endStyle();
td.text(rowValue.getServiceName());
td.endTD();
td = row.startTD();
td.className(cellStyles);
td.style().outlineStyle(OutlineStyle.NONE).endStyle();
td.text(rowValue.getSuperZoneCommission());
td.endTD();
td = row.startTD();
td.className(cellStyles);
td.style().outlineStyle(OutlineStyle.NONE).endStyle();
td.text(rowValue.getZoneCommission());
td.endTD();
// Last name column.
row.endTR();
}
}
private class CustomHeaderBuilder extends AbstractHeaderOrFooterBuilder<ServiceCategorywiseCommissionDetails> {
private Header<String> firstNameHeader = new TextHeader("Co mmission List");
public CustomHeaderBuilder() {
super(commissionListDataGrid, false);
setSortIconStartOfLine(false);
}
#Override
protected boolean buildHeaderOrFooterImpl() {
Style style = commissionListDataGrid.getResources().style();
String groupHeaderCell = "Header Cell";
// Add a 2x2 header above the checkbox and show friends columns.
TableRowBuilder tr = startRow();
tr.startTH().colSpan(2).rowSpan(2).className(style.header() + " " + style.firstColumnHeader());
tr.endTH();
/*
* Name group header. Associated with the last name column, so clicking on the group header sorts by last name.
*/
// Get information about the sorted column.
ColumnSortList sortList = commissionListDataGrid.getColumnSortList();
ColumnSortInfo sortedInfo = (sortList.size() == 0) ? null : sortList.get(0);
Column<?, ?> sortedColumn = (sortedInfo == null) ? null : sortedInfo.getColumn();
boolean isSortAscending = (sortedInfo == null) ? false : sortedInfo.isAscending();
// Add column headers.
tr = startRow();
buildHeader(tr, firstNameHeader, serviceType, sortedColumn, isSortAscending, false, false);
tr.endTR();
return true;
}
private void buildHeader(TableRowBuilder out, Header<?> header, Column<ServiceCategorywiseCommissionDetails, ?> column, Column<?, ?> sortedColumn, boolean isSortAscending, boolean isFirst,
boolean isLast) {
// Choose the classes to include with the element.
Style style = commissionListDataGrid.getResources().style();
boolean isSorted = (sortedColumn == column);
StringBuilder classesBuilder = new StringBuilder(style.header());
if (isFirst) {
classesBuilder.append(" " + style.firstColumnHeader());
}
if (isLast) {
classesBuilder.append(" " + style.lastColumnHeader());
}
// if (column.isSortable()) {
// classesBuilder.append(" " + style.sortableHeader());
// }
if (isSorted) {
classesBuilder.append(" " + (isSortAscending ? style.sortedHeaderAscending() : style.sortedHeaderDescending()));
}
// Create the table cell.
TableCellBuilder th = out.startTH().className(classesBuilder.toString());
// Associate the cell with the column to enable sorting of the
// column.
enableColumnHandlers(th, column);
// Render the header.
Context context = new Context(0, 2, header.getKey());
renderSortableHeader(th, context, header, isSorted, isSortAscending);
// End the table cell.
th.endTH();
}
}
public void setCommissionListDataGrid(ListDataProvider<ServiceCategorywiseCommissionDetails> dataProvider) {
GWT.log("inside set commissionListDataGrid size is " + dataProvider.getList().size());
commissionListDataGrid.setRowData(dataProvider.getList());
}
And I have a method in the presenter which calls the method set CommissionListDataGrid and sets its row value.
While doing this the data grid is not displayed. However if i add simplelayoutpanel in the following way in the constructor 'ZoneCommissionListView()'
RootPanel.get().add(commissionListLayoutPanel);
Then the data grid is displayed .What exactly am I missing .Any suggestion would be appreciated
DataGrid requires to be put in a LayoutPanel or Panel that implements
the ProvidesResize interface to be visible.
Source
And the SimpelLayoutPanel which you tested also implements the ProvidesResize Interface.
I'm trying to make a simple Drag and Drop FlexTable using native GWT drag events to allow the user to move rows around.
//This works fine
galleryList.getElement().setDraggable(Element.DRAGGABLE_TRUE);
galleryList.addDragStartHandler(new DragStartHandler() {
#Override
public void onDragStart(DragStartEvent event) {
event.setData("text", "Hello World");
groupList.getElement().getStyle().setBackgroundColor("#aff");
}
});
However, I'd like to:
1. Give a visual indicator where the item will be dropped.
2. Work out where i should drop the row, when the drop event fires.
galleryList.addDragOverHandler(new DragOverHandler() {
#Override
public void onDragOver(DragOverEvent event) {
//TODO: How do i get the current location one would drop an item into a flextable here
}
});
galleryList.addDragEndHandler(new DragEndHandler() {
#Override
public void onDragEnd(DragEndEvent event) {
//TODO: How do i know where i am in the flextable
}
});
I see these FlexTable methods are useful in getting a cell/row:
public Cell getCellForEvent(ClickEvent event)
protected Element getEventTargetCell(Event event)
But the problem is the Drag events do not inherit of Event
Thanks in advance
Caveat: I cant gaurentee this will work out the box. This is the code I ended up making (And works for me) - it's a Drag n Drop Widget which inherits from FlexTable. I detect any drag events on the table, and then try compute where the mouse is over that FlexTable.
import com.google.gwt.dom.client.TableRowElement;
import com.google.gwt.event.dom.client.*;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Widget;
public class DragFlexTable extends FlexTable implements DraggableWidget {
public String dragStyle = "drag-table-row";
public String dragReplaceStyle;
protected DragVerticalHandler dragFlexTableHandler;
private int currentRow;
private int[] yLocations;
private int rowBeingDragged;
DragFlexTable() {
sinkEvents(Event.ONMOUSEOVER | Event.ONMOUSEOUT);
getElement().setDraggable(Element.DRAGGABLE_TRUE);
final DragUtil dragUtil = new DragUtil();
addDragStartHandler(new DragStartHandler() {
#Override
public void onDragStart(DragStartEvent event) {
dragUtil.startVerticalDrag(event, DragFlexTable.this);
}
});
addDragEndHandler(new DragEndHandler() {
#Override
public void onDragEnd(DragEndEvent event) {
dragUtil.endVerticalDrag(event, DragFlexTable.this);
}
});
addDragOverHandler(new DragOverHandler() {
#Override
public void onDragOver(DragOverEvent event) {
dragUtil.handleVerticalDragOver(event, DragFlexTable.this, 3);
}
});
}
#Override
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
Element td = getEventTargetCell(event);
if (td == null) return;
Element tr = DOM.getParent(td);
currentRow = TableRowElement.as(td.getParentElement()).getSectionRowIndex();
switch (DOM.eventGetType(event)) {
case Event.ONMOUSEOVER: {
//tr.addClassName(ROW_STYLE_NAME + "-mouseover");
tr.addClassName(dragStyle);
break;
}
case Event.ONMOUSEOUT: {
tr.removeClassName(dragStyle);
break;
}
}
}
public void setDragStyle(String dragStyle) {
this.dragStyle = dragStyle;
}
#Override
public void resetDragState() {
yLocations = null;
}
#Override
public void setRowBeingDragged(int currentRow) {
this.rowBeingDragged = currentRow;
}
#Override
public int getDragRow(DragDropEventBase event) {
if (yLocations == null) {
yLocations = new int[getRowCount()];
for (int i = 0; i < getRowCount(); i++) {
Widget widget = getWidget(i, 0);
if (widget.isVisible()) {
com.google.gwt.dom.client.Element imgTd = widget.getElement().getParentElement();
int absoluteBottom = imgTd.getAbsoluteBottom();
yLocations[i] = absoluteBottom;
} else {
yLocations[i] = -1;
}
}
}
int lastY = 0;
for (int i = 0; i < yLocations.length; i++) {
int absoluteBottom = yLocations[i];
//invisible
if (absoluteBottom != -1) {
int absoluteTop = lastY;
int clientY = event.getNativeEvent().getClientY();
if (absoluteBottom > clientY && absoluteTop < clientY) {
//com.google.gwt.dom.client.Element tr = imgTd.getParentElement();
return i;
}
lastY = absoluteBottom;
}
}
return currentRow;
}
#Override
public com.google.gwt.dom.client.Element getTrElement(int row) {
return getWidget(row, 0).getElement().getParentElement().getParentElement();
}
#Override
public DragVerticalHandler getDragFlexTableHandler() {
return dragFlexTableHandler;
}
public void setDragReplaceStyle(String dragReplaceStyle) {
this.dragReplaceStyle = dragReplaceStyle;
}
#Override
public int getRowBeingDragged() {
return rowBeingDragged;
}
#Override
public String getDragReplaceStyle() {
return dragReplaceStyle;
}
public void setDragFlexTableHandler(DragVerticalHandler dragFlexTableHandler) {
this.dragFlexTableHandler = dragFlexTableHandler;
}
}
This is util class which it uses
import com.google.gwt.event.dom.client.DragEndEvent;
import com.google.gwt.event.dom.client.DragOverEvent;
import com.google.gwt.event.dom.client.DragStartEvent;
import com.google.gwt.user.client.ui.Image;
public class DragUtil {
private int alternateIgnoreEvent = 0;
private int lastDragRow = -1;
public void startVerticalDrag(DragStartEvent event, DraggableWidget widget) {
widget.resetDragState();
//Required
event.setData("text", "dragging");
int currentRow = widget.getDragRow(event);
widget.setRowBeingDragged(currentRow);
if (widget.getDragFlexTableHandler()!=null) {
Image thumbnailImg = widget.getDragFlexTableHandler().getImage(currentRow);
if (thumbnailImg!=null) {
event.getDataTransfer().setDragImage(thumbnailImg.getElement(), -10, -10);
}
}
}
public void handleVerticalDragOver(DragOverEvent event, DraggableWidget widgets, int sensitivity) {
if (alternateIgnoreEvent++ % sensitivity != 0) {
//many events fire, for every pixel move, which slow the browser, so ill ignore some
return;
}
int dragRow = widgets.getDragRow(event);
if (dragRow != lastDragRow) {
com.google.gwt.dom.client.Element dragOverTr = widgets.getTrElement(dragRow);
if (lastDragRow != -1) {
com.google.gwt.dom.client.Element lastTr = widgets.getTrElement(lastDragRow);
lastTr.removeClassName(widgets.getDragReplaceStyle());
}
lastDragRow = dragRow;
dragOverTr.addClassName(widgets.getDragReplaceStyle());
}
}
public void endVerticalDrag(DragEndEvent event, DraggableWidget widgets) {
int newRowPosition = widgets.getDragRow(event);
//cleanup last position
if (newRowPosition != lastDragRow) {
com.google.gwt.dom.client.Element lastTr = widgets.getTrElement(lastDragRow);
lastTr.removeClassName(widgets.getDragReplaceStyle());
}
if (newRowPosition != widgets.getRowBeingDragged()) {
com.google.gwt.dom.client.Element dragOverTr = widgets.getTrElement(newRowPosition);
dragOverTr.removeClassName(widgets.getDragReplaceStyle());
widgets.getDragFlexTableHandler().moveRow(widgets.getRowBeingDragged(), newRowPosition);
}
}
}
In the uibinder I then use it like this:
<adminDnd:DragFlexTable ui:field='itemFlexTable' styleName='{style.table}' cellSpacing='0'
cellPadding='0'
dragStyle='{style.drag-table-row-mouseover}'
dragReplaceStyle='{style.drag-replace-table-row}'
/>
Even i had this problem and after a little prototyping this is what I ended up with
.I created a class which extended the flex table.Here is the code
public class DragFlexTable extends FlexTable implements
MouseDownHandler,MouseUpHandler,MouseMoveHandler,
MouseOutHandler
{
private int row,column,draggedrow,draggedcolumn;
private Element td;
private Widget w;
private boolean emptycellclicked;
DragFlexTable()
{
sinkEvents(Event.ONMOUSEOVER | Event.ONMOUSEOUT | Event.ONMOUSEDOWN | Event.ONMOUSEMOVE);
this.addMouseDownHandler(this);
this.addMouseMoveHandler(this);
this.addMouseUpHandler(this);
this.addMouseOutHandler(this);
}
#Override
public void onBrowserEvent(Event event)
{
super.onBrowserEvent(event);
td = getEventTargetCell(event);
if (td == null)
{
return;
}
Element tr = DOM.getParent((com.google.gwt.user.client.Element) td);
Element body = DOM.getParent((com.google.gwt.user.client.Element) tr);
row = DOM.getChildIndex((com.google.gwt.user.client.Element) body, (com.google.gwt.user.client.Element) tr);//(body, tr);
column = DOM.getChildIndex((com.google.gwt.user.client.Element) tr, (com.google.gwt.user.client.Element) td);
}
boolean mousedown;
#Override
public void onMouseDown(MouseDownEvent event)
{
if (event.getNativeButton() == NativeEvent.BUTTON_LEFT)
{
//to ensure empty cell is not clciked
if (!td.hasChildNodes())
{
emptycellclicked = true;
}
event.preventDefault();
start(event);
mousedown = true;
}
}
#Override
public void onMouseMove(MouseMoveEvent event)
{
if (mousedown)
{
drag(event);
}
}
#Override
public void onMouseUp(MouseUpEvent event)
{
if (event.getNativeButton() == NativeEvent.BUTTON_LEFT)
{
if (!emptycellclicked)
{
end(event);
}
emptycellclicked = false;
mousedown = false;
}
}
#Override
public void onMouseOut(MouseOutEvent event)
{
this.getCellFormatter().getElement(row, column).getStyle().clearBorderStyle();
this.getCellFormatter().getElement(row, column).getStyle().clearBorderColor();
this.getCellFormatter().getElement(row, column).getStyle().clearBorderWidth();
w.getElement().getStyle().setOpacity(1);
mousedown = false;
}
private void start(MouseDownEvent event)
{
w = this.getWidget(row, column);
w.getElement().getStyle().setOpacity(0.5);
}
private void drag(MouseMoveEvent event)
{
if (draggedrow != row || draggedcolumn != column)
{
this.getCellFormatter().getElement(draggedrow, draggedcolumn).getStyle().clearBorderStyle();
this.getCellFormatter().getElement(draggedrow, draggedcolumn).getStyle().clearBorderColor();
this.getCellFormatter().getElement(draggedrow, draggedcolumn).getStyle().clearBorderWidth();
this.draggedrow = row;
this.draggedcolumn = column;
this.getCellFormatter().getElement(row, column).getStyle().setBorderStyle(BorderStyle.DASHED);
this.getCellFormatter().getElement(row, column).getStyle().setBorderColor("black");
this.getCellFormatter().getElement(row, column).getStyle().setBorderWidth(2, Unit.PX);
}
}
private void end(MouseUpEvent event)
{
insertDraggedWidget(row, column);
}
private void insertDraggedWidget(int r,int c)
{
this.getCellFormatter().getElement(r, c).getStyle().clearBorderStyle();
this.getCellFormatter().getElement(r, c).getStyle().clearBorderColor();
this.getCellFormatter().getElement(r, c).getStyle().clearBorderWidth();
w.getElement().getStyle().setOpacity(1);
if (this.getWidget(r, c) != null)
{
//pushing down the widgets already in the column
// int widgetheight = (this.getWidget(r, c).getOffsetHeight() / 2) + this.getWidget(r, c).getAbsoluteTop();
// int rw;
//placing the widget above the dropped widget
for (int i = this.getRowCount() - 1; i >= r; i--)
{
if (this.isCellPresent(i, c))
{
this.setWidget(i + 1, c, this.getWidget(i, c));
}
}
}
this.setWidget(r, c, w);
//removes unneccesary blank rows
cleanupRows();
//pushing up the column in the stack
// for (int i = oldrow;i<this.getRowCount()-1 ;i++)
// {
//
// this.setWidget(i ,oldcolumn, this.getWidget(i+1, oldcolumn));
//
// }
}
private void cleanupRows()
{
ArrayList<Integer> rowsfilled = new ArrayList<Integer>();
for (int i = 0; i <= this.getRowCount() - 1; i++)
{
for (int j = 0; j <= this.getCellCount(i) - 1; j++)
{
if (this.getWidget(i, j) != null)
{
rowsfilled.add(i);
break;
}
}
}
//replace the empty rows
for (int i = 0; i < rowsfilled.size(); i++)
{
int currentFilledRow = rowsfilled.get(i);
if (i != currentFilledRow)
{
for (int j = 0; j < this.getCellCount(currentFilledRow); j++)
{
this.setWidget(i, j, this.getWidget(currentFilledRow, j));
}
}
}
for (int i = rowsfilled.size(); i < this.getRowCount(); i++)
{
this.removeRow(i);
}
}
public HandlerRegistration addMouseUpHandler(MouseUpHandler handler)
{
return addDomHandler(handler, MouseUpEvent.getType());
}
public HandlerRegistration addMouseDownHandler(MouseDownHandler handler)
{
return addDomHandler(handler, MouseDownEvent.getType());
}
public HandlerRegistration addMouseMoveHandler(MouseMoveHandler handler)
{
return addDomHandler(handler, MouseMoveEvent.getType());
}
public HandlerRegistration addMouseOutHandler(MouseOutHandler handler)
{
return addDomHandler(handler, MouseOutEvent.getType());
}
}
and the on module load for the above custom widget is
public void onModuleLoad()
{
Label a = new Label("asad");
Label b = new Label("ad");
Label c = new Label("qwad");
Label w = new Label("zxd");
a.setPixelSize(200, 200);
a.getElement().getStyle().setBorderStyle(BorderStyle.SOLID);
a.getElement().getStyle().setBorderWidth(1, Unit.PX);
b.setPixelSize(200, 200);
c.setPixelSize(200, 200);
w.setPixelSize(200, 200);
a.getElement().getStyle().setBackgroundColor("red");
b.getElement().getStyle().setBackgroundColor("yellowgreen");
c.getElement().getStyle().setBackgroundColor("lightblue");
w.getElement().getStyle().setBackgroundColor("grey");
DragFlexTable d = new DragFlexTable();
d.setWidget(0, 0, a);
d.setWidget(0, 1, b);
d.setWidget(1, 0, c);
d.setWidget(1, 1, w);
d.setCellPadding(20);
RootPanel.get().add(d);
}
I am trying to make a straight ended connection between widgets.But when I am doing so, the orientation of my connector is coming wrong.Its always coming parallel to the required one.Also , it is independent of the connecting widgets i.e when I move my widget, my connector does not move.Snippet of my code is given as :
Link to snapshot of the problem: http://goo.gl/JUEmJ
public class DragNDropPage {
SyncCurrentUser cu = SyncCurrentUser.getUser();
private AbsolutePanel area = new AbsolutePanel();
HorizontalPanel toolsPanel = new HorizontalPanel();
AbsolutePanel canvas = new AbsolutePanel();
DragController toolboxDragController;
Label startLabel = new Label("START");
Label stopLabel = new Label("STOP");
Label activityLabel = new Label("ACTIVITY");
Label processLabel = new Label("PROCESS");
Button stopDrag = new Button("Done Dragging");
Button saveButton = new Button("Save");
PickupDragController dragController = new PickupDragController(area, true);
AbsolutePositionDropController dropController = new AbsolutePositionDropController(area);
private List<Widget> selected = new ArrayList<Widget>();
private List<Widget> onCanvas = new ArrayList<Widget>();
private List<Connection> connections = new ArrayList<Connection>();
private CActivity[] aItems;
private CProcess[] pItems;
MyHandler handler = new MyHandler();
int mouseX,mouseY;
String style;
public DragNDropPage() {
toolboxDragController = new ToolboxDragController(dropController, dragController);
RootPanel.get("rightbar").add(area);
area.setSize("575px", "461px");
area.add(toolsPanel);
toolsPanel.setSize("575px", "37px");
toolsPanel.add(startLabel);
startLabel.setSize("76px", "37px");
toolboxDragController.makeDraggable(startLabel);
toolsPanel.add(stopLabel);
stopLabel.setSize("66px", "37px");
toolboxDragController.makeDraggable(stopLabel);
toolsPanel.add(activityLabel);
activityLabel.setSize("82px", "36px");
toolboxDragController.makeDraggable(activityLabel);
toolsPanel.add(processLabel);
processLabel.setSize("85px", "36px");
toolboxDragController.makeDraggable(processLabel);
stopDrag.addClickHandler(handler);
toolsPanel.add(stopDrag);
stopDrag.setWidth("114px");
saveButton.addClickHandler(handler);
toolsPanel.add(saveButton);
area.add(canvas, 0, 36);
canvas.setSize("575px", "425px");
Event.addNativePreviewHandler(new Event.NativePreviewHandler() {
#Override
public void onPreviewNativeEvent(NativePreviewEvent event) {
//46 is the key code for Delete Button
if(event.getNativeEvent().getKeyCode() == 46 && !selected.isEmpty()) {
for (Iterator<Widget> i = selected.listIterator(); i.hasNext();) {
Widget w = (Widget) i.next();
UIObjectConnector.unwrap(w);
i.remove();
w.removeFromParent();
onCanvas.remove(i);
}
}
}
});
aItems = cu.currentUser.getcActivity();
pItems = cu.currentUser.getcProcess();
}
private class ToolboxDragController extends PickupDragController {
public ToolboxDragController(final DropController dropController, final DragController nodesDragController) {
super(area ,false);
setBehaviorDragProxy(true);
registerDropController(dropController);
addDragHandler(new DragHandlerAdapter(){
public void onPreviewDragEnd(DragEndEvent event) throws VetoDragException {
Widget node = (Widget) event.getSource();
int left = event.getContext().desiredDraggableX;
int top = event.getContext().desiredDraggableY;
AbsolutePanel panel = (AbsolutePanel) dropController.getDropTarget();
createConnector((Label) node, panel, left, top);
throw new VetoDragException();
}
});
}
}
protected UIObjectConnector createConnector(Label proxy, AbsolutePanel panel, int left, int top) {
Widget w;
String str = proxy.getText();
if(str.equals("START") || str.equals("STOP")){
w = new Label(proxy.getText()){
public void onBrowserEvent(Event event) {
if( DOM.eventGetType(event) == 4
&& DOM.eventGetCtrlKey(event)){
select(this);
}
super.onBrowserEvent(event);
}
};
w.getElement().setClassName("dnd-start-stop");
}
else{
w = new ListBox(){
public void onBrowserEvent(Event event) {
if( DOM.eventGetType(event) == 4
&& DOM.eventGetCtrlKey(event)){
select(this);
}
super.onBrowserEvent(event);
}
};
if(str.equals("ACTIVITY")){
getAItems((ListBox)w);
//w.getElement().addClassName("dnd-activity");
}
else if(str.equals("PROCESS")){
getPItems((ListBox)w);
//w.getElement().addClassName("dnd-process");
}
}
onCanvas.add(w);
left -= panel.getAbsoluteLeft();
top -= panel.getAbsoluteTop();
//panel.add(w,10,10);
panel.add(w, left, top);
dragController.makeDraggable(w);
return UIObjectConnector.wrap(w);
}
private void getAItems(ListBox w) {
for(int i=0;i<aItems.length;i++)
w.addItem(aItems[i].getActivityName());
}
private void getPItems(ListBox w) {
/*for(int i=0;i<pItems.length;i++)
w.addItem(pItems[i].getProcessName());*/
w.addItem("Process1");
}
protected void select(Widget w){
if(selected.isEmpty()) {
selected.add(w);
w.getElement().addClassName("color-green");
} else if(selected.contains(w)){
selected.remove(w);
w.getElement().removeClassName("color-green");
} else if(selected.size() == 1) {
Widget w2 = (Widget) selected.get(0);
connect(UIObjectConnector.getWrapper(w2), UIObjectConnector.getWrapper(w));
selected.clear();
}
}
protected void connect(Connector a, Connector b) {
//System.out.println(a.getLeft());
//System.out.println(b.getLeft());
add(new StraightTwoEndedConnection(a,b));
}
private void add(StraightTwoEndedConnection c) {
canvas.add(c);
connections.add(c);
c.update();
}
protected void remove(Connection c) {
connections.remove(c);
}
class MyHandler implements ClickHandler{
#Override
public void onClick(ClickEvent event) {
Button name = (Button) event.getSource();
if(name.equals(stopDrag)){
if(name.getText().equals("Done Dragging")){
for(Iterator<Widget> i = onCanvas.listIterator();i.hasNext();){
Widget w = (Widget) i.next();
dragController.makeNotDraggable(w);
}
name.setText("Continue");
}
else {
for(Iterator<Widget> i = onCanvas.listIterator();i.hasNext();){
Widget w = (Widget) i.next();
dragController.makeDraggable(w);
}
name.setText("Done Dragging");
}
}
else{
}
}
}
}
I know this is quite old, but I was having similar issues with the gwt-connector library.
The connectors will not appear in the correct placement if you are using standards mode. Use quirks mode instead.
Additionally, you need to manually perform a connector.update() while your dnd components are being dragged (in your drag listener) for the connection to move with the endpoint while you are dragging.