NatTable - Strange behavior when sorting - nattable

I have a nattable with sort/filter capabilities based off of
http://www.eclipse.org/nattable/documentation.php?page=sorting
and example 6031_GlazedListsFilterExample.java
Initially my table has zero rows.
Scenario 1:
I view a CTabItem that contains a NatTable with no rows.
If I then populate the rows and click on the column headers, nothing happens (sorting seems disabled).
Scenario 2:
I do NOT view a CTabItem that contains the NatTable with no rows.
I then populate the rows
I then view the CTabItem that contains the NatTable which now has rows.
I click on the column headers and everything sorts as expected (sorting seems enabled)
Scenario 3:
I do NOT view a CTabItem that contains the NatTable with no rows.
I then populate the rows
I then view the CTabItem that contains the NatTable which now has rows.
I then remove all row data
I click on the column headers and everything sorts as expected (sorting seems enabled). * even though there are no rows I still see the up/down icons appear in the column header cell
Is there a reason that the column header actions are not 'updated' after the initial 'view' of the NatTable? In other words, it seems to take the presence/absence of rows into account for the rest of the tables life after the first time the NatTable is viewed, regardless of if the rows change.
Relevant Code sections shown below:
private CompositeLayer createExampleLayer(Collection<T> values,
IColumnPropertyAccessor<T> columnPropertyAccessor,
IDataProvider columnHeaderDataProvider, IConfigRegistry
configRegistry, Matcher<T> matcher) {
BodyLayerStack<T> bodyLayerStack = new BodyLayerStack<>(
values, columnPropertyAccessor);
// build the column header layer
DataLayer columnHeaderDataLayer = new
DefaultColumnHeaderDataLayer(columnHeaderDataProvider);
ILayer columnHeaderLayer = new
ColumnHeaderLayer(columnHeaderDataLayer, bodyLayerStack,
bodyLayerStack.getSelectionLayer());
SortHeaderLayer<T> sortHeaderLayer = new SortHeaderLayer<>
(columnHeaderLayer, new GlazedListsSortModel<T>
(bodyLayerStack.getSortedList(), columnPropertyAccessor,
configRegistry,
bodyLayerStack.getBodyDataLayer()), false);
FilterRowHeaderComposite<T> filterRowHeaderLayer = new
FilterRowHeaderComposite<>(
new DefaultGlazedListsFilterStrategy<T>
(bodyLayerStack.getFilterList(), columnPropertyAccessor,
configRegistry),
sortHeaderLayer, columnHeaderDataLayer.getDataProvider(),
configRegistry);
// Omitted code for rowHeaderLayer and cornerLayer
return new GridLayer(bodyLayerStack, filterRowHeaderLayer,
rowHeaderLayer, cornerLayer);
}
public BodyLayerStack(Collection<T> values,
IColumnPropertyAccessor<T> columnPropertyAccessor) {
eventList = GlazedLists.eventList(values);
TransformedList<T, T> rowObjectsGlazedList =
GlazedLists.threadSafeList(eventList);
this.sortedList = new SortedList<>(rowObjectsGlazedList, null);
// wrap the SortedList with the FilterList
this.filterList = new FilterList<>(sortedList);
this.bodyDataProvider = new ListDataProvider<>(this.filterList,
columnPropertyAccessor);
this.bodyDataLayer = new DataLayer(getBodyDataProvider());
// layer for event handling of GlazedLists and PropertyChanges
GlazedListsEventLayer<T> glazedListsEventLayer = new
GlazedListsEventLayer<>(bodyDataLayer, this.filterList);
this.selectionLayer = new SelectionLayer(glazedListsEventLayer);
ViewportLayer viewportLayer = new ViewportLayer(getSelectionLayer());
setUnderlyingLayer(viewportLayer);
}
private void enableSorting() {
this.nattable.addConfiguration(new SingleClickSortConfiguration());
}

Looks like the creation of your SortHeaderLayer is not correct. The last parameter of the GlazedListsSortModel needs to be the IDataLayer of the column header, not the body layer.
Changing your code to the following should make things work. It did at least on my side.
SortHeaderLayer<T> sortHeaderLayer = new SortHeaderLayer<>
(columnHeaderLayer, new GlazedListsSortModel<T>
(bodyLayerStack.getSortedList(), columnPropertyAccessor,
configRegistry,
columnHeaderDataLayer), false);

Related

itext 7 - how to configure table splitting

I have a couple of issues with tables rendered with itext 7. I use itext 7.0.2.2 (C# edition).
First, when table starts close to the bottom of the page and page has space only for header, itext 7 renders header on the first page, and page breaks right after header. How to force keeping header and the first row together?
Next issue is that itext 7 splits row instead of moving whole row to the next page. I know itext 5 have setSplitLate(bool) method that configures itext to split row or not, but what to do with itext 7? See what's happens with row:
Note that row can be empty and should have minimum height, so setKeepTogether(true) on cell's content is not a solution. I add cells this way:
table.AddCell(new Cell().SetMinHeight(MIN_HEIGHT).Add("foo"));
UPDATE:
Here is a repro for row splitting (C#):
var writer = new PdfWriter(new FileStream("...", FileMode.Create));
var pdfDoc = new PdfDocument(writer);
using (var document = new Document(pdfDoc, PageSize.A4))
{
var table = new iText.Layout.Element.Table(UnitValue.CreatePercentArray(new[] { 1.3f, 1f, 1f, 1f, 1f, 1f, 1f }))
.SetWidthPercent(100f)
.SetFixedLayout();
foreach (var i in Enumerable.Range(1, 7 * 100)) // 100 rows
{
var cell = new Cell().SetKeepTogether(true).SetMinHeight(45).Add(i.ToString());
table.AddCell(cell);
}
document.Add(table);
}
Result:
set the table header cells. tbl.addHeaderCell( new Cell().add("head txt"));
this will force the headers to repeat in new pages from my experiences.
then just add content in the cells for the columns like normal.

ToggleGroup in a GXT ColumnConfig

I'm using a ColumnConfig for presenting and editing data. For the gender I wann to have RadioButtons which where defined by an enumeration.
In every row i want to have:
id | (x) male ( ) female | name | date
The only way I have found was adding a "button" with defined rendering code. But there I cannot get the values or actions for pushed radio.
ColumnConfig<SomeValueGto, String> begIdCol = createColumnConfig(begIdProvider, "Id", sizeBegId);
//gender
ColumnConfig<SomeValueGto, GenderCode> genderCol = createColumnConfig(GRID_PROPERTIES.sex(), "Sex*", sizeGender);
ColumnConfig<SomeValueGto, String> nameCol = createColumnConfig(GRID_PROPERTIES.name(), "Name*", sizeName);
ColumnConfig<SomeValueGto, Date> birthdateCol = createColumnConfig(GRID_PROPERTIES.birthdate(), "Birthdate*", sizeBirthdate);
DateCell gebCell = new DateCell(DateTimeFormat.getFormat("dd.MM.yyyy"));
geburtsdatumCol.setCell(gebCell);
//add fields to the row
List<ColumnConfig<SomeValueGto, ?>> columnList = new ArrayList<ColumnConfig<SomeValueGto, ?>>();
columnList.add(begIdCol);
columnList.add(genderCol);
columnList.add(nameCol);
columnList.add(birthdateCol);
ColumnModel<SomeValueGto> cm = new ColumnModel<SomeValueGto>(columnList);
ListStore<SomeValueGto> gridStore = new ListStore<SomeValueGto>(GRID_PROPERTIES.id());
myGrid = new SLGrid<SomeValueGto>(gridStore, cm);
// empty entries. default ids 1/2/3
myGrid.getStore().add(new SomeValueGto(1));
myGrid.getStore().add(new SomeValueGto(2));
myGrid.getStore().add(new SomeValueGto(3));
final GridInlineEditing<SomeValueGto> editing = new GridInlineEditing<SomeValueGto>(myGrid);
editing.setErrorSummary(false);
editing.addEditor(nameCol, new TextField());
final SLDateField dateField = new SLDateField("date", false, true);
editing.addEditor(geburtsdatumCol, new Converter<Date, Date>() {.....}, dateField);
The helper createColumnConfig:
private <T> ColumnConfig<SomeValueGto, T> createColumnConfig(ValueProvider<SomeValueGto, T> aValueProvider, String aHeader, int aWidth) {
ColumnConfig<SomeValueGto, T> columnCol = new ColumnConfig<SomeValueGto, T>(aValueProvider);
columnCol.setHeader(aHeader);
columnCol.setWidth(aWidth);
columnCol.setMenuDisabled(true);
return columnCol;
}
Does anyone have already solved a problem like this?
GXT Grids uses com.google.gwt.cell.client.Cell to render data in the grid. I don't think the kind of cell you want exist in GXT. So I think you will have to implement your own cell. You can take example of ColorPaletteCell, which allow the user to select a color from the cell itself.
So you will need to implement the render and onBrowserEvent methods to manage your radio buttons and what append when the user click on it.

How to force cellTable to show all data (GWT)?

Here I have itemDetailTable
CellTable<List<String>> itemDetailTable = new CellTable<List<String>>();
ListDataProvider<List<String>> dataProvider = new ListDataProvider<List<String>>();
dataProvider.addDataDisplay(itemDetailTable);
final ScrollPanel itemDetailScrollPanel=new ScrollPanel();
FlowPanel itemDetailFlowPanel=new FlowPanel();
itemDetailFlowPanel.add(itemDetailTable);
itemDetailScrollPanel.add(itemDetailFlowPanel);
Now my List<List<String>> has 16 rows, however, after ran it showed the table with 15 rows only. If I want to see the row 16 then need to click on the last cell of the table (the cell in the bottom right handside of the table) & enter arrow-down key then it will show the record 16.
If i use Simplepager
SimplePager itemDetailPager = new SimplePager();
itemDetailPager.setDisplay(itemDetailTable);
then it will have 2 page, the 1st page has 15 records and the 2nd page has 1 record.
That is not OK as I want the table to show all the records at once and won't hide any records.
Someone said that maybe cos I use List<String> & that is causing the problem, but I am not sure if that is the main cause.
But If I only has 14 records, then it showed all 14 records without any problem.
SO How to fix it?
Try any one
Just pass page size while constructing CellTable that constructs a table with the given page size.
int pageSize=16;
CellTable<List<String>> itemDetailTable = new CellTable<List<String>>(pageSize);
use CellTable#setPageSize() to set the number of rows per page and refresh the view.
CellTable<List<String>> itemDetailTable = new CellTable<List<String>>();
itemDetailTable.setPageSize(16);
Note: use GWT.create() to construct the SimplePager.Resources object with as shown below:
SimplePager.Resources pagerResources = GWT.create(SimplePager.Resources.class);
// pass the parameters as per your requirement
SimplePager pager = new SimplePager(TextLocation.CENTER, pagerResources, false, 0, true);

How to coloriate differently even rows and odd rows of a List in LWUIT?

There is a List in a LWUIT application. I want to make odd rows and even rows to be of different colors. How to achieve that ?
You can set two differents UIIDs to the rows. Setting this UIID you can modify selectively the colors of your rows.
EDIT
Ok this will be more difficult.
You need to make a Render and set it in your List with List.setRender(Render r).
The ´Render´ class will extend from ListCellRender. In this class you can set UIID to the Render, setting its Selected or Unselected styles.
See this example. #Shai Almog could have more info for your problem.
http://www.lwuit.com/2008/07/lwuit-list-renderer-by-chen-fishbein.html
What you need is the Generic List Cell Renderer, you will probably have to create the styles in code, or set the UIID from the resource editor.
List list = new List(createGenericListCellRendererModelData());
list.setRenderer(new GenericListCellRenderer(createGenericRendererContainer(), createGenericRendererContainer()));
private Container createGenericRendererContainer() {
Container c = new Container(new BorderLayout());
c.setUIID("ListRenderer");
Label name = new Label();
name.setFocusable(true);
name.setName("Name");
c.addComponent(BorderLayout.CENTER, name);
Label surname = new Label();
surname.setFocusable(true);
surname.setName("Surname");
c.addComponent(BorderLayout.SOUTH, surname);
CheckBox selected = new CheckBox();
selected.setName("Selected");
selected.setFocusable(true);
c.addComponent(BorderLayout.WEST, selected);
return c;
}
private Hashtable[] createGenericListCellRendererModelData() {
Hashtable[] data = new Hashtable[5];
data[0] = new Hashtable();
data[0].put("Name", "Shai");
data[0].put("Surname", "Almog");
data[0].put("Selected", Boolean.TRUE);
data[1] = new Hashtable();
data[1].put("Name", "Chen");
data[1].put("Surname", "Fishbein");
data[1].put("Selected", Boolean.TRUE);
data[2] = new Hashtable();
data[2].put("Name", "Ofir");
data[2].put("Surname", "Leitner");
data[3] = new Hashtable();
data[3].put("Name", "Yaniv");
data[3].put("Surname", "Vakarat");
data[4] = new Hashtable();
data[4].put("Name", "Meirav");
data[4].put("Surname", "Nachmanovitch");
return data;
}
Full details here : http://lwuit.blogspot.com/2011/03/list-rendering-easy-way-generic-list.html (code gotten from this link).

Editable SWT table

How to edit SWT table Values without Using Mouse Listeners?
Do the TableEditor snippets in the below link help?
SWT Snippets
The first example in the TableEditor section uses a SelectionListener on the table (unlike the second example which uses a MouseDown event you mentioned you don't want)
You could perhaps make use of the TraverseListener or KeyListener too to help you achieve what you want.
final int EDITABLECOLUMN = 1;
tblProvisionInfo.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
// Clean up any previous editor control
final TableEditor editor = new TableEditor(tblProvisionInfo);
// The editor must have the same size as the cell and must
// not be any smaller than 50 pixels.
editor.horizontalAlignment = SWT.LEFT;
editor.grabHorizontal = true;
editor.minimumWidth = 50;
Control oldEditor = editor.getEditor();
if (oldEditor != null)
oldEditor.dispose();
// Identify the selected row
TableItem item = (TableItem) e.item;
if (item == null)
return;
// The control that will be the editor must be a child of the
// Table
Text newEditor = new Text(tblProvisionInfo, SWT.NONE);
newEditor.setText(item.getText(EDITABLECOLUMN));
newEditor.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent me) {
Text text = (Text) editor.getEditor();
editor.getItem()
.setText(EDITABLECOLUMN, text.getText());
}
});
newEditor.selectAll();
newEditor.setFocus();
editor.setEditor(newEditor, item, EDITABLECOLUMN);
}
});
Here tblProvision is the name of your table. you can just now edit Your table by clicking on it. I have Declare EDITABLECOLUMN. this is the column that u want to edit.
If you can use JFace as well and not just pain SWT, have a look at the JFace Snippets, especially
Snippet036FocusBorderCellHighlighter - Demonstrates keyboard navigation by highlighting the currently selected cell with a focus border showing once more the flexibility of the new cell navigation support
Snippet034CellEditorPerRowNewAPI - Demonstrates different CellEditor-Types in one COLUMN with 3.3-API of JFace-Viewers
You can get or set the value of a item, for example:
Table table = new Table(parent, SWT.NONE);
TableItem item = new TableItem(table, SWT.NONE);
item.setText("My new Text");
I suggest you to us TableViewer, it is very powerful table which it you can use databinding very easy too.