JasperReport 4.1.2 - Using complex Java Bean and subreports - jasper-reports

I'm facing a problem when trying to generate a report based on some java bean's.
Suppose I have this configuration: a master bean, say
Bean1
String name
String age
ArrayList bean2
Bean2
String text
ArrayList
Bean3 is the last child of the tree and it is composed by:
String text
(I have more levels but this is enough for you to understand)
I'm using SubReport component to access data inside every ArrayList of a bean and it works well (using JRBeanCollectionDataSource()).
The problem is that, at Bean3, I have acess to all text fields of every Bean2. For example: I have an ArrayList<Bean2> of size 2: bean2_1 and bean2_2.
bean2_1 has an ArrayList<Bean3> of size 2 and bean2_2 has an ArrayList of size 3.
When I print the content of Bean3 (field text) for bean2_1 and bean2_2, it shows all 5 text values for all my beans: bean2_1 and bean2_2.
Anyone had already faced this problem? How can i bind the differente levels to show only the correct data??
Can anyone help ?

Related

Print List<String> each element in new field

I am fresh in JasperReports and I'm having problems solving an issue.
I have a report and a field $F{therapies} that is type of List<String>. If I print this field, the whole List is printed as a single String. Is it possible to print each element of the list in a new line or better - as a new Text Field.
If I try, for instance, $F{therapies}.get(1), it prints correctly the element at position 1. But since the size of List isn't constant I can't solve it that way.
I hope you understand what I want to achieve . Somehow printing List<String> per element.
I solved my problem using subreport and passing List as a datasource.
Here is a link: Passing the List of primitive type objects as datasource for subreport

JavaFX error: incompatible types - Object cannot be converted to Node

I have defined 3 labels in a FXML file within a grid pane. I am trying to read the following XML file and display the labels present in the file in a grid pane. The numerical values in the XML file denotes the row & column position.
<data>
<lbl1>0,0</lbl1>
<lbl2>0,1</lbl2>
<lbl3>0,2</lbl3>
</data>
I have added all the elements to the HashMap and then retrieve it to be displayed. Firstly, I added all the three labels one by one as follows:
hm.put("lbl1", eElement.getElementsByTagName("lbl1").item(0).getTextContent());
hm.put("lbl2", eElement.getElementsByTagName("lbl2").item(0).getTextContent());
hm.put("lbl3", eElement.getElementsByTagName("lbl3").item(0).getTextContent());
Then I display them as follows:
grid.add(lbl1, Integer.parseInt(hm.get("lbl1").toString().split(",")[0]),Integer.parseInt(hm.get("lbl1").toString().split(",")[1]));
grid.add(lbl2, Integer.parseInt(hm.get("lbl2").toString().split(",")[0]),Integer.parseInt(hm.get("lbl2").toString().split(",")[1]));
grid.add(lbl3, Integer.parseInt(hm.get("lbl3").toString().split(",")[0]),Integer.parseInt(hm.get("lbl3").toString().split(",")[1]));
The above code works well without any issues and I can see the labels on the grid.
Now, instead of adding the labels one by one, I added all of them in a single statement through a 'for' loop as shown below:
if (!eElement.getTagName().toString().equals("data"))
hm.put(eElement.getTagName(), eElement.getTextContent());
If I try to display the label, for example:
grid.add(hm.get("lbl1"),0,0);
I get an error:incompatible types - Object cannot be converted to Node.
If I try to typecast:
grid.add((javafx.scene.Node) hm.get("lbl1"),0,0);
I get an error:java.lang.ClassCastException: java.lang.String cannot be cast to javafx.scene.Node
If I print the hashmap entries, the following output is shown:
lbl1=0,0, lbl2=0,1, lbl3=0,2
How to fix this error? Is there any other way in which I can add all the elements in a single statement and then display them?
in your imports add:-
import javafx.scene.control.Label;
I suspect that the current import is from awt.
From your sample code, I guess that hm is an instance of Map<String, String>
So, when you call hm.get("lbl1") , you get a String.
You're trying to add this String to a GridPane, but the add() method is expecting a javafx.scene.Node. That's why you get a an error "incompatible types".
Instead, you should add your instances of javafx.scene.control.Label (lbl1, lbl2, lbl3)

JasperReports customize series labels based on a value other than the Category value

I have a JasperReport with a line chart that I need to display labels on, but I want them to display conditionally for each data point. I've created the customizer class to actually display the value, but I want to use a different field than the value field to decide if it should display or not.
Basically in my DataSet I have 3 fields:
Date: (Category Axis)
Value: (Value Axis)
PrintValue: Boolean field
I want to print the Value in the label only when PrintValue=true
One solution would be to override one of the methods implemented by JRDefaultScriptlet in a scriptlet class, then set the value of "PrintValue" in any manner you desire. Then in your chart dataset you should be able to reference $V{PRINTVALUE} as an operand.
I'm going to assume your using iReport for your report design.
Open your report in iReport and click the report name (Top most node in the report Inspector)
Set the Scriplet class to your package name and class, e.g., org.company.scriptlets.MyChartClass
Declare your report variable in iReport. In this case "PRINTVALUE" would be the variable name.
Create a java class that overrides a scriplet method, like beforeDetailEval, e.g.,:
#Override
public void beforeDetailEval() throws JRScriptletException {
super.beforeDetailEval();
...
this.setVariableValue("PRINTVALUE", true);
}
Since you want to display the category label conditionally for each tick mark, you'll probably need to use a Map of key/val pairs. key would be category label, value would be true/false for "PRINTVALUE". Note I did NOT illustrate this in the sample code above but its entirely possible. Just declare your report variable as a Map, e.g., HashMap<String, Boolean> hm.
You'll need to add your new scriplet class to the Classpath in iReport.
Hope this helps or at least gets you started.

How do I display HashMap and List property in Jasper

Hello All
I have a POJO class which have some property out of them two are of type
List someName;
TreeMap> myMap;
here I am getting this data from the above property and I would Like to show them on jasper report. I want to know what to write on jrxml file, I am using jasper version 1.0.2
Thanks in advance.
I don't believe you can easily display the values on a list or map using JasperReports directly from a POJO.
I believe you would have to wrap the POJO in a bean data source. See also:
http://jasperreports.sourceforge.net/api/net/sf/jasperreports/engine/data/JRAbstractBeanDataSource.html
http://jasperreports.sourceforge.net/api/net/sf/jasperreports/engine/data/JRBeanCollectionDataSource.html
Then, you "connect" to the bean data source and return the results as required.
This probably requires JasperReports version 3.0 or greater.

Struts and ValidatorForm --> does it work with variable number of form elements?

HI,
I have a form where I generate rows of input elements (using JavaScript) for users to enter their data. Each row contains data about a particular box that the user is entering (e.g. height, width, length, etc.). I've successfully gotten this form to work and I can read from the ActionForm into/out of an ArrayList object.
I'd like to validate these entries to catch invalid entries up front. (I'm on 1.3.10)
I can't seem to find any documentation about using ValidatorForm with a dynamic number of form elements. That is, I never know how many rows of boxes will be entered, and I wonder if anyone has successfully used Validator to validate dynamic form elements?
Is this even possible? Or am I resigned to implement the .validate() method?
Is it possible to use the Validator for some elements and leave the rest to the .validate() method? has anyone done this, and if so, what are the pitfalls?
I'd appreciate your comments or even a pointer to a resource where I can read up.
You can do this by making following steps.
1. Define a class (simple POJO) say DimensionBean; which contains the value of one row input elements (like height, width, length etc).
2. In your Form bean (child of ValidatorForm), define an array or list of DimensionBean. The name of the array is arrDimensionBeans.
3. In your validation.xml you can define it as follows
<field property="height" indexedListProperty="arrDimensionBeans" depends="validwhen">
<arg0 key="yourform.height.label"/>
<var>
<var-name>test</var-name>
<var-value>((arrDimensionBeans[].width == null) or (*this* != null))</var-value>
</var>
</field>
This will check height only if width is null or height is not null. You can change the var-value as per your requirement. Hope this will help you to solve your problem.