Can JRXML extend data source before using it? - jasper-reports

I use the same data source for generating several reports. One of the reports needs to be printed with a few empty lines ("reserve") at the bottom, so that users can manually write missing data by hand if needed.
E.g.:
+---------+-------------+
| item 1 | bla bla |
+---------+-------------+
| item 2 | foo |
+---------+-------------+
| | | <--- here user can just add forgotten
+---------+-------------+ items with a pen
| | |
+---------+-------------+
The easiest for the JRXML would be if there were several records of nulls at the end of the data source. Then it would just print its "details" band a few times with no text, just as required. However, the data source is reused for other reports which certainly don't want this.
Can I somehow inject such empty lines into the data source in JRXML itself, just before report filling?

You can modify your CustomDataSource and set it from jrxml to generate extra records when needed:
Example
public class JRExtraEmptyRecordsDataSource extends JRBeanCollectionDataSource {
private int nrOfEmptyRecords=0;
private int currentExtraRecord = 0;
public JRExtraEmptyRecordsDataSource(Collection<?> beanCollection) {
super(beanCollection);
}
#Override
public Object getFieldValue(JRField field) throws JRException {
if (currentExtraRecord==0){
return super.getFieldValue(field);
}
Class<?> theCorrectClass = field.getValueClass();
//Implement your logic to return correct class (reflection or switch) if you need speciall values
//or just return null
return null;
}
#Override
public boolean next() {
boolean next = super.next();
if (next){
return true;
}
currentExtraRecord++;
return currentExtraRecord<=nrOfEmptyRecords;
}
#Override
public void moveFirst() {
super.moveFirst();
currentExtraRecord=0;
}
public int getNrOfEmptyRecords() {
return nrOfEmptyRecords;
}
public int setNrOfEmptyRecords(int nrOfEmptyRecords) {
this.nrOfEmptyRecords = nrOfEmptyRecords;
return this.nrOfEmptyRecords;//Lets return something for variable
}
}
When you need extra empty records add this variable definition in your jrxml
<variable name="extraRecords" class="java.lang.Integer">
<initialValueExpression><![CDATA[((my.package.JRExtraEmptyRecordsDataSource)$P{REPORT_DATA_SOURCE}).setNrOfEmptyRecords(2)]]></initialValueExpression>
</variable>
I do not have custom datasource what can I do?
Normally without custom datasource, you can use the columnFooter with the attribute isFloatColumnFooter="true" (or a dummy group footer band) to display extra info at the end of your detail band. Probably I would choose this method anyway since it helps to customize the extra rows and avoid checking for null in the normal detail band
If you need dynamically to indicate the number of empty records, include a subreport with an empty record and pass as datasource JREmptyDataSource
new net.sf.jasperreports.engine.JREmptyDataSource(P{nrOfEmptyRecords})

Related

Simple Mybatis, how to obtain a collection?

It has been a long time since I have done this, and I simply cannot see the pattern to code MyBatis to get a collection, after spending a lot of time searching the examples and Mybatis docs.
The problem I have is with the examples and answers lacking the code to interpret it properly, understand, and integrate into my own code... or it simply does not work, returning this error (in most cases):
org.apache.ibatis.exceptions.TooManyResultsException: Expected one
result (or null) to be returned by selectOne(), but found: 3
I have simplified the query and everything else I am trying to accomplish. What I need is a mapper in XML format as well as the Java interface, as a simple and a plain example that works ...
SQL statement I am trying to execute:
SELECT * FROM MyTable;
The structure of the MyTable
+----+-------+
| id | value |
+----+-------+
| 1 | a |
| 2 | ab |
| 3 | abc |
+----+-------+
The model is:
public class MyTable{
private short id = 0;
private String value;
public short getId() {
return id;
}
public void setId(short id) {
this.id = id;
}
public String getValue() {
return value
}
public void setValue(String value) {
this.value = value;
}
}
What I need to obtain is a
List<MyTable>
I am aware that there are similar questions, however, neither is providing the answer in xml format for the mapper, or the answers are not easy to understand lacking the code to support the answer ... Therefore, I want to keep this as simple as possible, for anyone else trying to connect things without a success.
With the limited information provided, all I can show you is a super simple example.
test/Mapper.xml
<mapper namespace="test.Mapper">
<select id="selectAll" resultType="MyTable">
select * from MyTable
</select>
</mapper>
test/Mapper.java
package test;
import java.util.List;
public interface Mapper {
List<MyTable> selectAll();
}
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
Mapper mapper = sqlSession.getMapper(Mapper.class);
List<MyTable> list = mapper.selectAll();
}
Here is an executable demo project.

How to get the column name in nattable?

I had create an example like Editor Example, while the difference is that my demo can hide column. While when I hidden some column, I can not the collect selected column index, I changed my mind, I want to get the selected column's header name. How to get it?
Following is the handler to handle the selected column
But I don't know how to get the column name
public void handleLayerEvent(ILayerEvent event) {
if (event instanceof CellSelectionEvent) {
CellSelectionEvent cellEvent = (CellSelectionEvent) event;
int columnIndex = natTable.getColumnIndexByPosition(cellEvent.getColumnPosition());
SelectionLayer selectionLayer = cellEvent.getSelectionLayer();
........
}
You need the reference to the ColumnHeaderLayer and get the data value. E.g. ColumnHeaderLayer#getDataValueByPosition(int, int)

How to show rows-records between two tab form?

In my Form, I have Two TabPages, with the same DataSource for each.
In TabPageA I have all records from my DataSource. I select records in TabPageA and I want to only show, in TabPageB, those records I selected previously in TabPageA.
If I don't select anything in TabPageA I don't see anything in TabPageB
For example if in my GridA I selected Record#4 , in GridB I see only Record#4.
I don't think you'll be able to filter TabPageB differently from TabPageA easily due to the fact they share the same DataSource.
There are two quick ways to modify this.
Keep it as one DataSource:
Create a global QueryBuildRange to easily update the range on selected records.
public class FormRun extends ObjectRun
{
QueryBuildRange qbr;
}
Override the init of your datasource. Here you will set the qbr:
public void init()
{
super();
qbr = this.queryBuildDataSource().addRange(fieldNum(SalesTable, RecId));
}
Then override the pageActivated TabPage method for each to set the range and re-execute the query to your liking:
TabPageA:
public void pageActivated()
{
super();
qbr.value('');
SalesTable_ds.executeQuery();
}
TabPageB
public void pageActivated()
{
super();
element.createRange();
SalesTable_ds.executeQuery();
}
Method to update range:
public void createRange()
{
MultiSelectionHelper multiSelectionHelper = MultiSelectionHelper::createFromCaller(this);
common common;
Set set = new Set(Types::Int64);
// Necessary if the datasource you want is not the header datasource.
multiSelectionHelper.parmDatasource(SalesTable_ds);
common = multiSelectionHelper.getFirst();
while (common)
{
// Use of set not necessary, but a little cleaner.
set.add(common.RecId);
common = MultiSelectionHelper.getNext();
}
qbr.value(strRem(set.toString(), '"{}'));
}
This is somewhat dirty, but you get the idea and could clean it up as needed.
Two Datasources:
Update the range on the second datasource (used by TabPageB) based on the multi-selection of the first datasource. But I'm assuming you only want one datasource for some reason.

Nebula GridTreeViewer - Is there a way to show the filter like FilteredTree in eclipse?

I am using a Nebula GridTreeViewer for which I need to add filters like eclipse filters.
When we go to Window->Preferences, we get a filter on top of the left side tree which says 'type filter text'.
I tried the TreeViewer with the FilteredTree -
final FilteredTree filteredTree = new FilteredTree(parent, SWT.BORDER
| SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION,
new MyPatternFilter(), true);
TreeViewer treeViewer = filteredTree.getViewer();
The above code works fine for a TreeViewer.
Is there a similar way to attach such kind of a filter to a Nebula GridTreeViewer?
If yes, please tell me. Would be very helpful. Thanks.
You will have to create your own quick search adapter. Observe the code in FilteredTree.
I can't post my own adapter, since it's company property. Here are some hints.
Things you will need in your MyQuickSearchAdapter:
public QuickSearchAdapter(Composite parent) constructor
A setViewer(StructuredViewer) API that does this.viewer = viewer and this.viewer.addFilter(viewerFilter) (see below for viewerFilter)
An abstract method getLabelProvider() to access a viewer's LabelProvider (in our case, GridTreeViewer)
Creation methods for a Text field that will represent the quick search area.
(Optional) Creation method for a label/button that clears the text when clicked (as in FilteredTree) - although this is overkill, in my opinion.
private MyViewerFilter extends ViewerFilter nested class, that does the actual filtering. This will have a String instance field that holds the search text; this field will have a setter that will be called each time you type something in the filter box. Will look something like viewerFilter.setSearchText(filterBox.getText());. This nested class will also override the select(Viewer, Object, Object), which will use the getLabelProvider().getText(element) to extract the text for a certain cell. Something like:
// Automatically adds wildcard characters before and after search string:
public static final String QSEARCH_REGEX_PATTERN = "(.*)%s(.*)"; //$NON-NLS-1$
private class MyViewerFilter extends ViewerFilter
{
// --------------------- <Instance Fields> -----------------------
private String searchString;
// --------------------- <Setters> -----------------------
/**
* #param
* Text that goes inside the REGEX pattern
*/
public void setSearchText(final String searchString)
{
//this.searchString = "(.*)" + searchString.toLowerCase() + "(.*)"; //$NON-NLS-1$ //$NON-NLS-2$
this.searchString = String.format(QSEARCH_REGEX_PATTERN, searchString.toLowerCase());
}
// --------------------- <Overridden search method> -----------------------
#Override
public boolean select(final Viewer viewer, final Object parentElement, final Object element)
{
if (StringUtils.isEmpty(searchString))
return true;
final String text = getLabelProvider().getText(element);
if (StringUtils.isEmpty(text))
return true;
return text.toLowerCase().matches(searchString);
}
}
That's the hard part. After that, you just make a class called MyFilteredGridTreeViewer, and add the quick search adapter along side the grid viewer. Also remember to call quickSearchAdapter.setViewer(gridViewer), and you're done!

retrieve values from model in mvc2

I don't know how to create functions to retrieve the values.
*Table 1: OrgVasplans*
-Id
-vasplanId
-OrgId
-CreatedDate
Table-2: vasplans
-Id
-name
-amount
-validity
-vasdurationId
Table-3: VasDuration
Id
Duration.
These are my tables..
I have Controller named Candidatesvas and action method VasDetails....
I already stored the values into vasPlans table.
when I click in view "Details" link it will go to details page..
Then the values are retrieve from "Orgvasplans" table automatically without enter any input..
How to create methods for this....
I created some methods but the method contains only Name "field". I want to retrieve multiple values like "Amount", "validity" like that.....
Repository:
public IQueryable<VasPlan> GetVasPlans()
{
return from vasplan in _db.VasPlans
orderby vasplan.Name ascending
select vasplan;
}
public OrgVasPlan GetOrgVasPlan(int id)
{
return _db.OrgVasPlans.SingleOrDefault(v => v.Id == id);
}
public int AddOrgVasPlan(OrgVasPlan orgvasplan)
{
_db.OrgVasPlans.AddObject(orgvasplan);
Save();
return orgvasplan.Id;
}
public void AddVasPlan(VasPlan vasPlan)
{
_db.VasPlans.AddObject(vasPlan);
}
Controller
public ActionResult VasDetails(FormCollection collection)
{
OrgVasPlan orgvasplan = new OrgVasPlan();
orgvasplan.CreatedDate = DateTime.Now;
orgvasplan.OrgId = LoggedInOrganization.Id;
orgvasplan.vasplanId=??????????????
VasPlan vasplan = new VasPlan();
//if (!string.IsNullOrEmpty(collection["Name"])) ;
_repository.AddOrgVasPlan(orgvasplan);
_repository.Save();
return View();
}
Here i don't know how to put code here for get multiple values form vasplans table like(amount,name,validity etc...,)
this is my problem...
Make your view strongly-typed, make sure you create input elements whose names correspond to the model properties (or use HTML helpers, e.g. Html.TextBoxFor(model => model.Amount). That way MVC will automatically fill in the model for you when the action that should take the model as a argument, is invoked.
For example your action should be:
public ActionResult NewVasPlan(VasPlan vplan)
{
//check model state
//save or return error messages
}
Or you can simply add string and int parameters to the Action like this:
public ActionResult NewVasPlan(string name, int amount /*, etc*/)
{
//MVC will also automatically fill name, amount, from request POST or GET params
//(or cookies??)
}
Hope this helps, tell me if you need more info or if I misunderstood your question.