nattable combobox filter header with group by - nattable

I am trying to implement nattable with "ComboBoxFilterRowHeaderComposite".
Filtering is working fine but after filtering rows when I try to do group by, it throws following exception
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:653)
at java.util.ArrayList.remove(ArrayList.java:492)
at ca.odell.glazedlists.FunctionList.listChanged(FunctionList.java:283)
at ca.odell.glazedlists.event.ListEventAssembler$ListEventFormat.fire(ListEventAssembler.java:424)
at ca.odell.glazedlists.event.ListEventAssembler$ListEventFormat.fire(ListEventAssembler.java:421)
at ca.odell.glazedlists.event.SequenceDependenciesEventPublisher$SubjectAndListener.firePendingEvent(SequenceDependenciesEventPublisher.java:445)
at ca.odell.glazedlists.event.SequenceDependenciesEventPublisher.fireEvent(SequenceDependenciesEventPublisher.java:344)
at ca.odell.glazedlists.event.ListEventAssembler.commitEvent(ListEventAssembler.java:317)
at ca.odell.glazedlists.TransformedList.clear(TransformedList.java:98)
at org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.GroupByDataLayer$1.run(GroupByDataLayer.java:286)
at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
at org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.GroupByDataLayer.updateTree(GroupByDataLayer.java:272)
at org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.GroupByDataLayer.update(GroupByDataLayer.java:313)
at java.util.Observable.notifyObservers(Observable.java:159)
at java.util.Observable.notifyObservers(Observable.java:115)
at org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.GroupByModel.update(GroupByModel.java:124)
at org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.GroupByModel.addGroupByColumnIndex(GroupByModel.java:44)
Here is my structure for ComboBoxFilterRowHeaderComposite:
filterRowHeaderLayer = new ComboBoxFilterRowHeaderComposite<T>(
bodyLayerStack.getFilterList(),
bodyLayerStack.getGlazedListsEventLayer(), bodyLayerStack.getSortedList(),
columnAccessor, columnHeaderLayer, dataProvider, configRegistry);
where,
columnAccessor = new ReflectiveColumnPropertyAccessor(propertyNames);
columnGroupHeaderLayer = new DynamicColumnGroupHeaderLayer(sortHeaderLayerStack, bodyLayerStack.getSelectionLayer(),
bodyLayerStack.getColumnGroupModel(), tr);
DataProvider is com.vanguard.tip.epm.platform.ui.grid.next.DynamicColumnHeaderDataProvider;
After that
CornerLayerStack cornerLayerStack = new CornerLayerStack(rowHeaderLayerStack, filterRowHeaderLayer);
CompositeLayer gridLayer = new GridLayer(bodyLayerStack, filterRowHeaderLayer, rowHeaderLayerStack, cornerLayerStack);
Then Add gridLayer in GroupByHeaderLayer:
groupByHeaderLayer = new GroupByHeaderLayer(bodyLayerStack.getGroupByModel(), gridLayer, columnHeaderLayerStack.getDataProvider(),
new GroupByHeaderConfigurationWrapper(bodyLayerStack.getGroupByModel(), columnHeaderLayerStack.getDataProvider(), bodyLayerStack.getColumnGroupModel()));
CompositeLayer groupByComposite = new CompositeLayer(1, 2);
groupByComposite.setChildLayer(GroupByHeaderLayer.GROUP_BY_REGION, groupByHeaderLayer, 0, 0);
groupByComposite.setChildLayer("Grid", gridLayer, 0, 1);
I hope this will give you some clarity about my use of Nattable.
When I use text base filter with same structure Grouping is working fine:
filterStrategy = new DefaultGlazedListsFilterStrategy<T>(bodyLayerStack.getFilterList(), columnAccessor, configRegistry);
this.filterRowHeaderLayer = new FilterRowHeaderComposite<T>(filterStrategy, columnHeaderLayer, dataProvider, configRegistry);
Let me know if you need more information.

Seems to be a bug for that combination. I created the following ticket for this:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=508334

Related

Updating column in tableviwer

I have retrieved data from database and i am able to show it in Table of the Table Viewer but my task is on click of a row the data should be appear in another form from where i can edit it and on click of update the view should be updated with the new values.I am using viewer.addSelectionChangedListener to retrieve the selected row but i am not getting how to update the table .Please suggest me few ideas
I have written the below code in the constructor of my class so whenever object is created Table is generated and l1 is list of data which i am passing to another UI
input[i] = new MyModel(persons[i].getDateOfRegistration(), persons[i].getFirstName(),
persons[i].getMiddleName(), persons[i].getLastName(), persons[i].getGender(),
persons[i].getDob(), persons[i].getContactNumber(), persons[i].getMaritalStatus(),
persons[i].getAddress(), persons[i].getCountry(), persons[i].getBloodGroup(),
persons[i].getInsuranceDetails().getPolicyHolderName(),
persons[i].getInsuranceDetails().getPolicyNumber(),
persons[i].getInsuranceDetails().getSubscriberName(),
persons[i].getInsuranceDetails().getRelationshipToPatient());
viewer.setInput(input);
table.setHeaderVisible(true);
table.setLinesVisible(true);
GridData gridData = new GridData();
gridData.verticalAlignment = GridData.FILL;
gridData.horizontalSpan = 2;
gridData.grabExcessHorizontalSpace = true;
gridData.grabExcessVerticalSpace = true;
gridData.horizontalAlignment = GridData.FILL;
viewer.getControl().setLayoutData(gridData);
viewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
IStructuredSelection selection = (IStructuredSelection) event.getSelection();
StringBuffer sb = new StringBuffer("Selection - ");
int j = 0;
String[] s;
for (Iterator iterator = selection.iterator(); iterator.hasNext();) {
sb.append(iterator.next() + ", ");
System.out.println("Testing::" + sb);
}
System.out.println(sb);
String result[] = new String[18];
List l1 = new ArrayList(100);
String[] parts = sb.toString().split("=");
for (int i = 0; i < parts.length; i++) {
System.out.println("s" + parts[i]);
String[] s1 = parts[i].split(",");
l1.add(s1[0]);
}
SWTPatientRegistrationUpdatePageEventView swtPatientRegistrationUpdatePageEventView = new SWTPatientRegistrationUpdatePageEventView();
swtPatientRegistrationUpdatePageEventView.openParentUpdateShell(l1);
// viewer.refresh();
//flag=false;
//refreshingData(list);
}
});
Make sure we will follow table viewer MVC architecture all the time. Steps we can do to resolve your issue isas follow:
Create proper datastructure(Model Class) to hold the data. and use the same in array which you set in viewer.setInput()
When you click/double click on table row, fetch the data and save it in datastructure created(with new object).
Pass that data structure to your form dialog.
when you are done with update in form. Fill the updated data in new Model object again.
And after form close, pass that model object back to parent.
updated the corresponding array element with object received from Form Dialog and just refresh the tableviewer.
Please let me know if you need some code module. Thanks

Is it possible to merge several pdfs using iText7

I have several datasheets for products. Each is a separate file. What I want to do is to use iText to generate a summary / recommended set of actions, based on answers to a webform, and then append to that all the relevant datasheets. This way, I only need to open one new tab in the browser to print all information, rather than opening one for the summary, and one for each datasheet that is needed.
So, is it possible to do this using iText?
Yes, you can merge PDFs using iText 7. E.g. look at the iText 7 Jump-Start tutorial sample C06E04_88th_Oscar_Combine, the pivotal code is:
PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
PdfMerger merger = new PdfMerger(pdf);
//Add pages from the first document
PdfDocument firstSourcePdf = new PdfDocument(new PdfReader(SRC1));
merger.merge(firstSourcePdf, 1, firstSourcePdf.getNumberOfPages());
//Add pages from the second pdf document
PdfDocument secondSourcePdf = new PdfDocument(new PdfReader(SRC2));
merger.merge(secondSourcePdf, 1, secondSourcePdf.getNumberOfPages());
firstSourcePdf.close();
secondSourcePdf.close();
pdf.close();
(C06E04_88th_Oscar_Combine method createPdf)
Depending on your use case, you might want to use the PdfDenseMerger with its helper class PageVerticalAnalyzer instead of the PdfMerger here. It attempts to put content from multiple source pages onto a single target page and corresponds to the iText 5 PdfVeryDenseMergeTool from this answer. Due to the nature of PDF files this only works for PDFs without headers, footers, and similar artifacts.
I found a solution that works quite well.
public byte[] Combine(IEnumerable<byte[]> pdfs)
{
using (var writerMemoryStream = new MemoryStream())
{
using (var writer = new PdfWriter(writerMemoryStream))
{
using (var mergedDocument = new PdfDocument(writer))
{
var merger = new PdfMerger(mergedDocument);
foreach (var pdfBytes in pdfs)
{
using (var copyFromMemoryStream = new MemoryStream(pdfBytes))
{
using (var reader = new PdfReader(copyFromMemoryStream))
{
using (var copyFromDocument = new PdfDocument(reader))
{
merger.Merge(copyFromDocument, 1, copyFromDocument.GetNumberOfPages());
}
}
}
}
}
}
return writerMemoryStream.ToArray();
}
}
Use
DirectoryInfo d = new DirectoryInfo(INPUT_FOLDER);
var pdfList = new List<byte[]> { };
foreach (var file in d.GetFiles("*.pdf"))
{
pdfList.Add(File.ReadAllBytes(file.FullName));
}
File.WriteAllBytes(OUTPUT_FOLDER + "\\merged.pdf", Combine(pdfList));
Autor:
https://www.nikouusitalo.com/blog/combining-pdf-documents-using-itext7-and-c/
If you want to add two array of bytes and return one array of bytes as PDF/A
public static byte[] mergePDF(byte [] first, byte [] second) throws IOException {
// Initialize PDF writer
ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(arrayOutputStream);
// Initialize PDF document
PdfADocument pdf = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, new PdfOutputIntent("Custom", "",
"https://www.color.org", "sRGB IEC61966-2.1", new FileInputStream("sRGB_CS_profile.icm")));
PdfMerger merger = new PdfMerger(pdf);
//Add pages from the first document
PdfDocument firstSourcePdf = new PdfDocument(new PdfReader(new ByteArrayInputStream(first)));
merger.merge(firstSourcePdf, 1, firstSourcePdf.getNumberOfPages());
//Add pages from the second pdf document
PdfDocument secondSourcePdf = new PdfDocument(new PdfReader(new ByteArrayInputStream(second)));
merger.merge(secondSourcePdf, 1, secondSourcePdf.getNumberOfPages());
firstSourcePdf.close();
secondSourcePdf.close();
writer.close();
pdf.close();
return arrayOutputStream.toByteArray();
}
The question doesn't specify the language, so I'm adding an answer using C#; this works for me. I'm creating three separate but related PDFs then combining them into one.
After creating the three separate PDF docs and adding data to them, I combine them this way:
PdfDocument pdfCombined = new PdfDocument(new PdfWriter(destCombined));
PdfMerger merger = new PdfMerger(pdfCombined);
PdfDocument pdfReaderExecSumm = new PdfDocument(new PdfReader(destExecSumm));
merger.Merge(pdfReaderExecSumm, 1, pdfReaderExecSumm.GetNumberOfPages());
PdfDocument pdfReaderPhrases = new PdfDocument(new PdfReader(destPhrases));
merger.Merge(pdfReaderPhrases, 1, pdfReaderPhrases.GetNumberOfPages());
PdfDocument pdfReaderUncommonWords = new PdfDocument(new PdfReader(destUncommonWords));
merger.Merge(pdfReaderUncommonWords, 1, pdfReaderUncommonWords.GetNumberOfPages());
pdfCombined.Close();
So the combined PDF is a PDFWriter type of PdfDocument, and the merged pieces parts are PdfReader types of PdfDocuments, and the PdfMerger is the glue that binds it all together.
Here is the minimum C# code needed to merge file1.pdf into file2.pdf creating new merged.pdf:
var path = #"C:\Temp\";
var src0 = System.IO.Path.Combine(path, "merged.pdf");
var wtr0 = new PdfWriter(src0);
var pdf0 = new PdfDocument(wtr0);
var src1 = System.IO.Path.Combine(path, "file1.pdf");
var fi1 = new FileInfo(src1);
var rdr1= new PdfReader(fi1);
var pdf1 = new PdfDocument(rdr1);
var src2 = System.IO.Path.Combine(path, "file2.pdf");
var fi2 = new FileInfo(src2);
var rdr2 = new PdfReader(fi2);
var pdf2 = new PdfDocument(rdr2);
var merger = new PdfMerger(pdf0);
merger.Merge(pdf1, 1, pdf1.GetNumberOfPages());
merger.Merge(pdf2, 1, pdf2.GetNumberOfPages());
merger.Close();
pdf0.Close();
Here is a VB.NET solution using open source iText7 that can merge multiple PDF files to an output file.
Imports iText.Kernel.Pdf
Imports iText.Kernel.Utils
Public Function Merge_PDF_Files(ByVal input_files As List(Of String), ByVal output_file As String) As Boolean
Dim Input_Document As PdfDocument = Nothing
Dim Output_Document As PdfDocument = Nothing
Dim Merger As PdfMerger
Try
Output_Document = New iText.Kernel.Pdf.PdfDocument(New iText.Kernel.Pdf.PdfWriter(output_file))
'Create the output file (Document) from a Merger stream'
Merger = New PdfMerger(Output_Document)
'Merge each input PDF file to the output document'
For Each file As String In input_files
Input_Document = New PdfDocument(New PdfReader(file))
Merger.Merge(Input_Document, 1, Input_Document.GetNumberOfPages())
Input_Document.Close()
Next
Output_Document.Close()
Return True
Catch ex As Exception
'catch Exception if needed'
If Input_Document IsNot Nothing Then Input_Document.Close()
If Output_Document IsNot Nothing Then Output_Document.Close()
File.Delete(output_file)
Return False
End Try
End Function
USAGE EXAMPLE:
Dim success as boolean = false
Dim input_files_list As New List(Of String)
input_files_list.Add("c:\input_PDF1.pdf")
input_files_list.Add("c:\input_PDF2.pdf")
input_files_list.Add("c:\input_PDF3.pdf")
success = Merge_PDF_Files(input_files_list, "c:\output_PDF.pdf")
'Optional: handling errors'
if success then
'Files merged'
else
'Error merging files'
end if

Devexpress xtraChart How to assign x and y values?

I have values in datasource and there is no problem with datasource. I have to assign X and Y values to the chart. Chart throws an error and says there is no column with named "TotalInboundArrivals".
ChartControl chart = new ChartControl();
chart.Location = new Point(38, 301);
chart.Size = new Size(789, 168);
Series series = new Series("Series1", ViewType.Bar);
chart.Series.Add(series);
series.DataSource = ds;
series.ArgumentScaleType = ScaleType.Numerical;
series.ArgumentDataMember = "TotalInboundArrivals"; //throws error here
series.ValueScaleType = ScaleType.Numerical;
series.ValueDataMembers.AddRange(new string[] { "StartTime" }); //throws error here
((SideBySideBarSeriesView)series.View).ColorEach = true;
((XYDiagram)chart.Diagram).AxisY.Visible = true;
chart.Legend.Visible = true;
chart.Visible = true;
chart.Dock = DockStyle.Fill;
xtraTabPage1.Controls.Add(chart);
Where is my Problem? Any Suggestions?
Have you went through Series.DataSource Property. You are making the mistake of assigning DataSet as DataSource to series. Think about it, how could it search columns in Data Source. Try to assign Ds.Tables["TableName"] as the datasource.
Creating DataSource Table
private DataTable CreateChartData(int rowCount) {
// Create an empty table.
DataTable table = new DataTable("Table1");
// Add two columns to the table.
table.Columns.Add("Argument", typeof(Int32));
table.Columns.Add("Value", typeof(Int32));
// Add data rows to the table.
Random rnd = new Random();
DataRow row = null;
for (int i = 0; i < rowCount; i++) {
row = table.NewRow();
row["Argument"] = i;
row["Value"] = rnd.Next(100);
table.Rows.Add(row);
}
Specifying Series properties corresponding to datasource
Series series = new Series("Series1", ViewType.Bar);
chart.Series.Add(series);
// Generate a data table and bind the series to it.
series.DataSource = CreateChartData(50);
// Specify data members to bind the series.
series.ArgumentScaleType = ScaleType.Numerical;
series.ArgumentDataMember = "Argument";
series.ValueScaleType = ScaleType.Numerical;
series.ValueDataMembers.AddRange(new string[] { "Value" });
Check the Examples and go through the Creating Charts -> Providing Data section to better understand it.
Reference
Hope this helps.

Despite loading new data from code, report displays original data

as below i have code to display data,
it works very fine, while data available..
but it shows same data, if query doeent return any rows, it shows last loaded data,
even if query returns other data eventhough it shows last loaded data..
please help me out...
ReportDocument rptdoc = new ReportDocument();
Ds2 = new DataSet();
Ds2 = ClsPos.GetRejectedByPosition(int.Parse(Request.QueryString.Get("ID")));
string ReportName = Server.MapPath("RejectedCandidate.rpt");
rptdoc.Load(ReportName);
// Position Name
ParameterFields Parameters = new ParameterFields();
ParameterField idget = new ParameterField();
idget.Name = "PositionName";
ParameterDiscreteValue values = new ParameterDiscreteValue();
values.Value = Request.QueryString.Get("PositionName");
idget.CurrentValues.Add(values);
Parameters.Add(idget);
CRViewer1.ParameterFieldInfo = Parameters;
rptdoc.SetDataSource(Ds2.Tables["GetValues"]);
CRViewer1.ReportSource = ReportName;
CRViewer1.DisplayGroupTree = false;
use rptDoc.Refresh(); after loading report. i.e.
rptdoc.Load(ReportName);
rptDoc.Refresh();

GXT3/GWT - How to remove cells(HasCell) from compositeCell dynamically?

I have a list of cells which i'll send it as an argument to create a composite cell. In the below code i'm creating the cells and adding it to the list.
List<HasCell<SensorTreeModel, ?>> cells= new ArrayList<HasCell<SensorTreeModel,?>>();
com.sencha.project.client.ImageCell editSwitchIcon = new com.sencha.project.client.ImageCell(ButtonType.EDITSWITCH);
com.sencha.project.client.ImageCell editIcon = new com.sencha.project.client.ImageCell(ButtonType.EDIT);
com.sencha.project.client.ImageCell switchRoleIcon = new com.sencha.project.client.ImageCell(ButtonType.SWITCH);
com.sencha.project.client.ImageCell breakIcon = new com.sencha.project.client.ImageCell(ButtonType.BREAK);
com.sencha.project.client.ImageCell deleteIcon = new com.sencha.project.client.ImageCell(ButtonType.DELETE);
cells.add(editSwitchIcon);
cells.add(editIcon);
cells.add(switchRoleIcon);
cells.add(breakIcon);
cells.add(deleteIcon);
In the below code. I'm adding the list to the composite cell.(ActionCell)
actionsCol.setCell(new ActionCell(cells));
Now what if I want to delete the cells dynamically in the columnConfig(actionCell) depending on the object which is going into the column?