Adding header above of column titles in GWT datagrid - gwt

How can I add something like this in GWT datagird using CellTableBuilder?

This should work as a simply solution for provided case. Please replace "YourPage" to your real page, "YourClass" to your class and "yourColumn1", "yourColumn2" to your real columns, and "object.getYourColumnValue" to your real get value method. Please also don't forget to bind your data to the table (using: "ContactDatabase.get().addDataDisplay(dataGrid1);" as provided in showcase, or by "dataGrid1.setRowData(0, yourData);"
public class YourPage extends Composite {
...
// attributes
private Column<YourClass, String> yourColumn1;
private Column<YourClass, String> yourColumn2;
...
public DataGrid<YourClass> buildGrid() {
dataGrid1 = new DataGrid<YourClass>();
dataGrid1.setWidth("100%");
dataGrid1.setHeight("100%");
dataGrid1.setAutoHeaderRefreshDisabled(true);
// Generating columns
yourColumn1 = new Column<YourClass, String>(new TextCell()) {
#Override
public String getValue(YourClass object) {
return object.getYourColumnValue();
}
};
dataGrid1.addColumn(yourColumn1, "Column 1");
dataGrid1.setColumnWidth(0, 50, Unit.PCT);
yourColumn2 = new Column<YourClass, String>(new TextCell()) {
#Override
public String getValue(YourClass object) {
return object.getYourColumnValue();
}
};
dataGrid1.addColumn(yourColumn2, "Column 2");
dataGrid1.setColumnWidth(1, 50, Unit.PCT);
// setHeaderBuilder
dataGrid1.setHeaderBuilder(
new dataGrid1HeaderBuilder(
dataGrid1, false));
...
return dataGrid1;
}
// your private header builder class
private class dataGrid1HeaderBuilder extends AbstractHeaderOrFooterBuilder<YourClass> {
public tblValidatorsGroupsAnalysisResultsHeaderBuilder(
AbstractCellTable<YourClass> table, boolean isFooter) {
super(table, false);
setSortIconStartOfLine(false);
}
#Override
protected boolean buildHeaderOrFooterImpl() {
Style style = dataGrid1.getResources().style();
TableRowBuilder tr = startRow();
TableCellBuilder th = tr.startTH().colSpan(1);
th.style().trustedProperty("border-right", "10px solid yellow").cursor(Cursor.POINTER).endStyle();
th.text("Name").endTH();
// Your "Header" for 2 column
th = tr.startTH().colSpan(2);
th.text("Header").endTH();
// Add Column1 and Column2 headers
tr = startRow();
buildHeader(tr, new TextHeader("Column1"), yourColumn1, null, false, false, false);
buildHeader(tr, new TextHeader("Column2"), yourColumn2, null, false, false, false);
tr.endTR();
return true;
}
private void buildHeader(TableRowBuilder out, Header<?> header, Column<YourClass, ?> column,
Column<?, ?> sortedColumn, boolean isSortAscending, boolean isFirst, boolean isLast) {
Style style = dataGrid1.getResources().style();
boolean isSorted = (sortedColumn == column);
StringBuilder classesBuilder = new StringBuilder(style.header());
// Create the table cell.
TableCellBuilder th = out.startTH().className(classesBuilder.toString());
// Render the header.
Context context = new Context(0, 0, header.getKey());
renderSortableHeader(th, context, header, isSorted, isSortAscending);
// End the table cell.
th.endTH();
}
}
}

Related

Why my natable cannot be editable

I use the following code to create a natable and register the edit function by configuration. Why this table's cell cannot be editable?
public class NattableFactory {
public static Control createExampleControl(Composite parent) {
ColumnGroupModel columnGroupModel = new ColumnGroupModel();
ColumnHeaderLayer columnHeaderLayer;
parent.setLayout(new GridLayout());
// property names of the Person class
String[] propertyNames = { "firstName", "lastName", "gender", "married", "birthday", "street", "status" };
// mapping from property to label, needed for column header labels
Map<String, String> propertyToLabelMap = new HashMap<String, String>();
propertyToLabelMap.put("firstName", "Firstname");
propertyToLabelMap.put("lastName", "Lastname");
propertyToLabelMap.put("gender", "Gender");
propertyToLabelMap.put("married", "Married");
propertyToLabelMap.put("birthday", "Birthday");
propertyToLabelMap.put("street", "Street");
propertyToLabelMap.put("status", "Status");
// Body
DefaultBodyDataProvider<Person> bodyDataProvider = new DefaultBodyDataProvider<Person>(PersonService.getPersons(50),
propertyNames);
ColumnGroupBodyLayerStack bodyLayer = new ColumnGroupBodyLayerStack(new DataLayer(bodyDataProvider),
columnGroupModel);
// Column header
DefaultColumnHeaderDataProvider defaultColumnHeaderDataProvider = new DefaultColumnHeaderDataProvider(propertyNames,
propertyToLabelMap);
DefaultColumnHeaderDataLayer columnHeaderDataLayer = new DefaultColumnHeaderDataLayer(
defaultColumnHeaderDataProvider);
columnHeaderLayer = new ColumnHeaderLayer(columnHeaderDataLayer, bodyLayer, bodyLayer.getSelectionLayer());
ColumnGroupHeaderLayer columnGroupHeaderLayer = new ColumnGroupHeaderLayer(columnHeaderLayer,
bodyLayer.getSelectionLayer(), columnGroupModel);
columnGroupHeaderLayer.addColumnsIndexesToGroup("name", 0, 1);
columnGroupModel.getColumnGroupByIndex(0).setCollapseable(false);
columnGroupHeaderLayer.setGroupUnbreakable(0);
CompositeLayer compositeLayer = new CompositeLayer(1, 2);
compositeLayer.setChildLayer(GridRegion.COLUMN_HEADER, columnGroupHeaderLayer, 0, 0);
compositeLayer.setChildLayer(GridRegion.BODY, bodyLayer, 0, 1);
// register column label accumulator
final ColumnOverrideLabelAccumulator columnLabelAccumulator = new ColumnOverrideLabelAccumulator(bodyLayer);
bodyLayer.setConfigLabelAccumulator(columnLabelAccumulator);
columnLabelAccumulator.registerColumnOverrides(5, "street");
columnLabelAccumulator.registerColumnOverrides(2, "gender");
// Register create column group command handler
// Register column chooser
DisplayColumnChooserCommandHandler columnChooserCommandHandler = new DisplayColumnChooserCommandHandler(
bodyLayer.getSelectionLayer(), bodyLayer.getColumnHideShowLayer(), columnHeaderLayer, columnHeaderDataLayer,
columnGroupHeaderLayer, columnGroupModel);
bodyLayer.registerCommandHandler(columnChooserCommandHandler);
NatTable natTable = new NatTable(parent, compositeLayer, false);
natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
natTable.addConfiguration(new EditorConfiguration());
natTable.addConfiguration(new DefaultColumnHeaderStyleConfiguration());
natTable.addConfiguration(new DefaultSelectionStyleConfiguration());
GridDataFactory.fillDefaults().grab(true, true).applyTo(natTable);
natTable.configure();
return natTable;
}
}
class EditorConfiguration extends AbstractRegistryConfiguration {
#Override
public void configureRegistry(IConfigRegistry configRegistry) {
configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITABLE_RULE, IEditableRule.ALWAYS_EDITABLE);
registerEditors(configRegistry);
}
private void registerEditors(IConfigRegistry configRegistry) {
registerColumnStreetComboBox(configRegistry);
registerColumnGenderIcon(configRegistry);
}
private static void registerColumnStreetComboBox(IConfigRegistry configRegistry) {
// register a combobox editor for the street names
ComboBoxCellEditor comboBoxCellEditor = new ComboBoxCellEditor(Arrays.asList(PersonService.getStreetNames()));
configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITOR, comboBoxCellEditor, DisplayMode.NORMAL,
"street");
}
/**
* The following will register a CheckBoxCellEditor with custom icons for the column that carries the gender
* information. As a Gender is not a Boolean, there need to be a special converter registered. Note that such a
* converter needs to create a Boolean display value and create the canonical value out of a Boolean value again.
*
* To register a CheckBoxCellEditor, you need to
*
*
*
* 1.Register the editor
*
* 2.Register the painter corresponding to that editor
*
* 3.Register the needed converter
*
*
*
* #param configRegistry
*/
private void registerColumnGenderIcon(IConfigRegistry configRegistry) {
// register a CheckBoxCellEditor for column four
configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITOR, new CheckBoxCellEditor(),
DisplayMode.NORMAL, "gender");
// if you want to use the CheckBoxCellEditor, you should also consider
// using the corresponding CheckBoxPainter to show the content like a
// checkbox in your NatTable
// in this case we use different icons to show how this works
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_PAINTER,
new CheckBoxPainter(GUIHelper.getImage("arrow_up"), GUIHelper.getImage("arrow_down")), DisplayMode.NORMAL,
"gender");
// using a CheckBoxCellEditor also needs a Boolean conversion to work
// correctly
configRegistry.registerConfigAttribute(CellConfigAttributes.DISPLAY_CONVERTER, getGenderBooleanConverter(),
DisplayMode.NORMAL, "gender");
}
/**
* #return Returns a simple converter for the gender of a Person. {#link Gender#MALE} will be interpreted as true
* while {#link Gender#FEMALE} will be interpreted as false
*/
private IDisplayConverter getGenderBooleanConverter() {
return new DisplayConverter() {
#Override
public Object canonicalToDisplayValue(Object canonicalValue) {
if (canonicalValue instanceof Gender) {
return ((Gender) canonicalValue) == Gender.MALE;
}
return null;
}
#Override
public Object displayToCanonicalValue(Object displayValue) {
Boolean displayBoolean = Boolean.valueOf(displayValue.toString());
return displayBoolean ? Gender.MALE : Gender.FEMALE;
}
};
}
}
you can see I register the edit function by "natTable.addConfiguration(new EditorConfiguration());" I mean the column 2(gender) and 5(Street)
Adding the following 2 line below the instancing the compositeLayer will work.
compositeLayer.addConfiguration(new DefaultEditConfiguration());
compositeLayer.addConfiguration(new DefaultEditBindings());

Eclipse JFace/SWT ViewerFilter select never gets called

I'm trying to build a simple dialog with a TableViewer in it, along with a checkbox which would filter the data. However the table is empty and the filtering never gets done. Whats wrong with this code?
public class AsTestDialog extends TitleAreaDialog {
private Table table;
private AsTestFilter filter;
private TableViewer tableViewer;
public AsTestDialog(Shell parentShell) {
super(parentShell);
}
#Override
public void create() {
super.create();
setTitle("Table Test");
}
#Override
protected Control createDialogArea(Composite parent) {
Composite area = (Composite) super.createDialogArea(parent);
area.setLayout(new GridLayout(1, false));
tableViewer = new TableViewer(area, SWT.BORDER | SWT.FULL_SELECTION);
table = tableViewer.getTable();
table.setHeaderVisible(true);
table.setLinesVisible(true);
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
TableViewerColumn tableViewerColumn = new TableViewerColumn(tableViewer, SWT.NONE);
TableColumn tblclmnNewColumn = tableViewerColumn.getColumn();
tblclmnNewColumn.setWidth(130);
tblclmnNewColumn.setText("Column1");
TableViewerColumn tableViewerColumn_2 = new TableViewerColumn(tableViewer, SWT.NONE);
TableColumn tblclmnId = tableViewerColumn_2.getColumn();
tblclmnId.setWidth(150);
tblclmnId.setText("Column2");
Composite composite = new Composite(area, SWT.NONE);
composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
Button btnFilter = new Button(composite, SWT.CHECK);
btnFilter.setBounds(10, 10, 111, 20);
btnFilter.setText("Filter");
btnFilter.addSelectionListener(new SelectionListener() {
#Override
public void widgetSelected(SelectionEvent e) {
System.out.println("CHECKBOX SELECTED");
filter.setFilterType("foobar");
tableViewer.refresh();
}
#Override
public void widgetDefaultSelected(SelectionEvent e) {}
});
addTestData(table);
//Filter
filter = new AsTestFilter();
tableViewer.addFilter(filter);
tableViewer.getTable().pack();
tableViewer.refresh();
return area;
}
private void addTestData(Table table) {
TableItem item1 = new TableItem(table, SWT.NONE);
item1.setText(new String[] {"1","2"});
item1.setData("1");
TableItem item2 = new TableItem(table, SWT.NONE);
item2.setText(new String[] {"3","4"});
item2.setData("3");
}
}
The filter class:
public class AsTestFilter extends ViewerFilter {
private String filterType = "all";
public void setFilterType(String tp) {
this.filterType = tp;
}
#Override
public boolean select(Viewer viewer, Object parentElement, Object element) {
System.out.println("SELECT CALLED: "+filterType);
return true;
}
}
If you are using the JFace TableViewer you must use a 'content provider' set with
tableViewer.setContentProvider(provider);
and then call
tableViewer.setInput(input data);
creating TableItem objects directly will not work properly as TableViewer expects to create these objects itself.
If you have a simple array or List of objects the content provider can simply be:
tableViewer.setContentProvider(ArrayContentProvider.getInstance());
and the set input:
tableViewer.setInput(array or list);
Your filter is not called because you have not called setInput, the table viewer does nothing until this is called.
The ViewerFilter operates on the TableViewer's input, which will be null in your case as you aren't using tableViewer.setInput(model). Instead you are creating TableItems directly.
You will need to set up a content provider, label provider, and define a model which you can pass to .setInput for the table viewer, and remove the function which directly creates the TableItems.
Once you do this, the ViewerFilter should work.
There are plenty of tutorials around which describe this, including https://eclipse.org/articles/Article-Table-viewer/table_viewer.html and http://wiki.eclipse.org/index.php/JFaceSnippets

hyperlink cell in GWT CellTable

I have a cell table in GWT with textcells and buttoncell ,Now i want to add a hyperlinkCell in my celltable , is this possible ?
TextCell jobStatusCell = new TextCell();
jobStatusColumn = new Column<EmployerJobs, String>(jobStatusCell) {
#Override
public String getValue(EmployerJobs object) {
// int status = object.getJobStatusId();
/*
* if(status ==1) { return ""; } else
*/
// return "post job";
return "view";
}
};
I want some thing like this
HyperlinkCell jobStatusCell = new HyperLinkCell();
Thanks
do you mean this HyperlinkCell?
If not, you can write a normal hyperlink (linkCell )and put it as the content of a cell.
Try using the following Cell implementation
Be sure that you provide cell's value as an array of 2 String objects like:
String[] value = new String[2];
value[HyperTextCell.LINK_INDEX] = "http://www.google.com";
value[HyperTextCell.TEXT_INDEX] = "Search on google";
public class HyperTextCell extends AbstractCell<String[]> {
interface Template extends SafeHtmlTemplates {
#Template("<a target=\"_blank\" href=\"{0}\">{1}</a>")
SafeHtml hyperText(SafeUri link, String text);
}
private static Template template;
public static final int LINK_INDEX = 0, URL_INDEX = 1;
/**
* Construct a new ImageCell.
*/
public HyperTextCell() {
if (template == null) {
template = GWT.create(Template.class);
}
}
#Override
public void render(Context context, String[] value, SafeHtmlBuilder sb) {
if (value != null) {
// The template will sanitize the URI.
sb.append(template.hyperText(UriUtils.fromString(value[LINK_INDEX]), value[URL_INDEX]));
}
}
}

How to hide column in Cell table GWT?

I am using Cell Table in GWT.In that cell table I am adding these columns.
TextColumn<Document> idColumn = new TextColumn<Document>() {
#Override
public String getValue(Document object) {
return Long.toString(object.getId());
}
};
TextColumn<Document> refColumn = new TextColumn<Document>() {
#Override
public String getValue(Document object) {
return object.getReferenceNumber();
}
};
/*
* DateCell dateCell = new DateCell(); Column<Contact, Date> dateColumn
* = new Column<Contact, Date>(dateCell) {
*
* #Override public Date getValue(Contact object) { return
* object.birthday; } };
*/
TextColumn<Document> nameColumn = new TextColumn<Document>() {
#Override
public String getValue(Document object) {
return object.getDocumentName();
}
};
table = new CellTable<T>();
table.addColumn(idColumn, "Id");
table.addColumn(refColumn, "Reference Number");
table.addColumn(nameColumn, "Name");
}
Now I have some queries:
How to hide the id column?
On click of row how can i get the from selected row?
Please help me out.
Thanks in advance.
Well you could try to use fixed layout for the CellTable and set the width of the specific column you want to hide to 0px.
I did use another approach.
In my case I have a cellTable which should display a checkbox column as soon as I press a button (which puts the celltable in edit mode).
I do this by creating a CheckBoxColumn and inserting and removing it when I press on the button. It looks seomething like that:
#Override
public void insertCheckBoxColumn(Column<Object,Boolean> column) {
if (cellTable.getColumnIndex(column) == -1) {
cellTable.addColumn(column,"");
cellTable.setColumnWidth(column,50, Unit.PX);
}
}
#Override
public void removeCheckBoxColumn(Column<Object, Boolean> column) {
int index = cellTable.getColumnIndex(column);
if (index != -1)
cellTable.removeColumn(index);
}
However note that you might run into this issue on google chrome.

how to convert flextable cell into editable text cell in GWT

Here is the code I tried to make the flextable's cell editable
The flex table is loaded with db values, when user clicks on the cell of flextable, it has to become editable and the user entered value has to be stored in db, after the user clicks submit button which is present at each row.
I'm using EditTextCell(), to make the cell editable but it not becoming editable when I test it. I have included all my codes below. Please let me know , if i'm missing anything.
private List<PendingChange<?>> pendingChanges = new ArrayList<PendingChange<?>>();
private List<AbstractEditableCell<?, ?>> editableCells = new ArrayList<AbstractEditableCell<?, ?>>();
CellTable cellTable= new CellTable<MessageEvent>();
EditTextCell editCell = new EditTextCell();
protected FlexTable flextable;
//flextable creation
private final void createWorkflows(List<MessageEvent> theWorkflowMessageEvents, boolean isSelectAll) {
int row = 1;
if (theWorkflowMessageEvents != null) {
for (final MessageEvent workflowMessageEvent : theWorkflowMessageEvents) {
flextable.getRowFormatter().setStyleName(row,ACTIVE_COLLECTION);
flextable.getCellFormatter().setHorizontalAlignment(row, 0, HasHorizontalAlignment.ALIGN_LEFT);
flextable.getCellFormatter().setWordWrap(row, 0, false);
flextable.setText(row, 0, workflowMessageEvent.getTransferReceived());
flextable.getCellFormatter().setHorizontalAlignment(row, 1, HasHorizontalAlignment.ALIGN_LEFT);
flextable.getCellFormatter().setWordWrap(row, 1, false);
flextable.setText(row, 1, workflowMessageEvent.getLoadReceived());
makeFlexTableEditable() ;
Button submitButton= new Button("Submit");
flextable.getCellFormatter().setHorizontalAlignment(row, 3, HasHorizontalAlignment.ALIGN_LEFT);
flextable.getCellFormatter().setWordWrap(row, 3, false);
flextable.setWidget(row, 3,submitButton );
submitWorklow(submitButton,row, workflowMessageEvent);
flextable.getRowFormatter().setVisible(row, true);
row++;
}
}
}
//adding flextable to main panel
protected void displayPendingWorkflows(final List<MessageEvent> theWorkflowMessageEvents) {
this.createPendingWorkflows(theWorkflowMessageEvents, false);
//some code
mainPanel.add(flextable);
mainPanel.add(cellTable);
}
//code for making flex table editable for TransferReceived column
private void makeFlexTableEditable() {
addColumn(new EditTextCell(), new GetValue() {
#Override
public String getValue(MessageEvent workflowMessageEvent) {
return workflowMessageEvent.getTransferReceived();
}
}, new FieldUpdater<MessageEvent, String>() {
public void update(int index, MessageEvent workflowMessageEvent, String value) {
try { pendingChanges.add(new TransferReceived(workflowMessageEvent, value));
}catch (Exception e) {
}
}
});
}
private <C> Column<MessageEvent, String> addColumn(EditTextCell cell,
final GetValue<String> getter,FieldUpdater<MessageEvent, String> fieldUpdater) {
Column<MessageEvent, String> transColumn = new Column<MessageEvent, String>(cell){
#Override
public String getValue(MessageEvent object) {
return getter.getValue(object);
}
};
transColumn.setFieldUpdater(fieldUpdater);
if (cell instanceof AbstractEditableCell<?, ?>) {
editableCells.add((AbstractEditableCell<?, ?>) cell);
}
cellTable.addColumn(transColumn);
return transColumn;
}
/**
* A pending change to a {#link MessageEvent}. Changes aren't committed
* immediately to illustrate that cells can remember their pending changes.
*
* #param <T> the data type being changed
*/
private abstract static class PendingChange<T> {
private final MessageEvent message;
private final T value;
public PendingChange(MessageEvent message, T value) {
this.message = message;
this.value = value;
}
/**
* Commit the change to the contact.
*/
public void commit() {
doCommit(message, value);
}
/**
* Update the appropriate field in the .
*
* #param message to update
* #param value the new value
*/
protected abstract void doCommit(MessageEvent message, T value);
}
/**
* Updates the Transfered Received.
*/
private static class TransferReceived extends PendingChange<String> {
public TransferReceived(MessageEvent message, String value) {
super(message, value);
}
#Override
protected void doCommit(MessageEvent message, String value) {
message.setTransferReceived(value);
}
}
/**
* Get a cell value from a record.
*
* #param <C> the cell type
*/
private static interface GetValue<C> {
C getValue(MessageEvent message);
}
I did something like this in my app. Sorry if the syntax is a bit off but the main idea is to use a clickevent and then get this events position and exchange the widget in that position.
final FlexTable flexTable = new FlexTable();
flexTable.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
Cell cell = flexTable.getCellForClickEvent(event);
final int row = cell.getRow();
final int column = cell.getIndex();
final TextBox textBox = new TextBox();
// Get the text from the cell in some way. Maybe use flextTable.getHTML(row, column) or what ever you prefer
// textBox.setText("Something other than this");
textBox.addKeyDownHandler(new KeyDownHandler() {
public void onKeyDownEvent(KeyDownEvent event) {
int code = event.getNativeKeyCode();
if (KeyCodes.KEY_ENTER == code) {
flexTable.setWidget(row, column, new Label(textBox.getText()));
}
}
});
flexTable.setWidget(row, column, textBox);
// You may also need something like this
textBox.setFocus(true);
}
});