Hello,
just a brief question regarding the iReport NB platform. Is it possible to write a plug-in for iReport NB where the source of the plugin is modified by an external program?
48 Answers:
I had not the time to write a plugin tutorial yet, but I can summarize here the steps.
An ireport plugin is just a plugin for NetBeans, so basically all the NetBeans plugin development tutorials will work just fine.
How to start:
1. Install the NetBeans 6.0.1 platform somewhere (you can install NetBeans 6.0.1 and configure it in a different version of NB as platform, or you can just downlaod the platform zip file here: http://download.netbeans.org/netbeans/6.0/final/zip/netbeans-6.0.1-200801291616-ml.zip
2. Add the platform to your NetBeans IDE (Tools->NetBeans platform)
3. Get the iReport source code from SVN (svn checkout --username anonsvn http://jasperforge.org/svn/repos/ireportfornetbeans) or from a src distribution of iReport
4. Open the ireport project (it's the ireport directory itself), compile and run iReport
5. Start creating your new plugin (it can be part of the iReport suite, then you can export it using create NBM feature of NetBeans). Remember to add as dependency for your plugin the ireport-designer module.
Feel you free to contact me directly for any question about plugin development for iReport (giulio@jaspersoft.com)
Good Luck!
Giulio
Hi Giulio,
I just started migrating my DataBasePlugin from Classic to NB Version. (although the missing barcode will prevent me upgrading at all, but I hope sometimes the barcode support will come!?! )
I successfully added a window like the JasperServer Plugin does... so far no problem.
But now I need an external Jar for connecting to our Application-Server. Where do I have to put it that the IDE knows the needed classes?
When I use the ADD LIBRARY manager, it will add a new module (what I doesn't want)
I can see, that all your external libs are located under D:\iReport\iReport-nb-3.5.0-src\ireport\modules\ext
When I copy my jar within that directory my new PluginModule can't find the needed classes.
So where can I add those external jars needed for my plugin!?!??!
hoping for your support + regards from very sunny Germany
C-Box
In your module project you find a file called: project.xml (Project Metadata). Inside this xml you declare you extra jars (that you will put in modules/ext directory of your module).
I.e.:
<class-path-extension>
<runtime-relative-path>ext/batik-bridge.jar</runtime-relative-path>
<binary-origin>release/modules/ext/batik-bridge.jar</binary-origin>
</class-path-extension>
If the jar must be used by the ireport-designer module (i.e. it is a datasource or something used during the design process), you have to add your jars to the iReport classpath too (because NetBeans prevents modules to see the classpath of the other ones). This can be done programmatically with an Installer class (see the NetBeans development docs to see how to create an install class, there is a wizard for that), and with the following lines of code:
List<String> cp = IReportManager.getInstance().getRelodableClasspath();
if (!cp.contains(""+newFile))
{
cp.add(""+newFile);
IReportManager.getInstance().setRelodableClasspath(cp);
}
You can use the iReport classloader whenever you want setting the thread classloader to IReportManager.getInstance().getReportClassloader()
Giulio
Thx Giulio so far... now it works without the separate module. Is there no "GUI Wizzard" for adding an external jar (like in eclipse) instead of editing the xml by hand?!?
quite tricky the netbeans environment if you primary work with eclipse.
regards from sunny Germany
C-Box
Hi Guilio,
I just found some time again to migrate my plugin for new nb-ireport version further.
So I'm now able to load our designs from database and open the JRXML files in iReport - fine so far. :-)
code:
DataObject obj = DataObject.find(org.openide.filesystems.FileUtil.toFileObject(singleRep.getFile()));
OpenCookie ocookie = obj.getCookie(OpenCookie.class);
if (ocookie != null) {
ocookie.open();
}
Now I have a tree holding our designs. (see screenshot attached)
When I click at a node I want the corresponding design activated in "MainFrame". As there isn't any FileTree as in classic old version I can't find the way you did in classic version (there I looped through the opened files and found the ReportFrame).
So could you please give me a hint, how I can find the DesignFrame towards my ReportObject within the tree (I just have the opened file - I could also link the ocookie to my node-UserObject if needed)
quite complex the new structure :-O
tia
regards from rainy Germany
C-Box
Ok.. I'm not sure but I think I got the meaning with the Cookie and DataObject.Find method (holding an instance and open makes everything for you -> also switching to the frame no matter if it was already openend, isn't it !??!?!)
Now I want when switching the frames manually that the nodes within my tree also get selected (each opened JRXML is one node in my tree)... so is there a way to register a kind of listener that is called when switching the frames in designer that I could change my tree selection????
tia
C-Box
well, the simple thing you are asking for is actually really complicated in NetBeans.
This is what can help a little bit. IReportManager allows you to add an JrxmlVisualViewActivatedListener:
public final void addJrxmlVisualViewActivatedListener(JrxmlVisualViewActivatedListener l)
If you are switching to preview or XML view, I assume you don't get any event, so be carreful.
My suggestion is to check if there is a visual view available after getting that event:
JrxmlVisualView view = IReportManager.getInstance().getActiveVisualView();
if (view != null) { .... }
If can be a good starting point...
Giulio
Hi Giulio,
As I load and save my JRXMLs into DataBase via my plugin I got again the message "File was modified externally, reload it?"....
Perhaps you could remember, that I had this problem some years ago too, when I started to develop my classic plugin and you introduced an option "Reload externally modified file without asking".
Could you please add this option again?
regards from sunny Germany
C-Box
Post Edited by CBox at 05/13/2009 11:04
There are lots of problems with the source distribution building on my install of NetBeans. The jasperreprots-components project is missing. I completely removed it and the build then occurs. There are a *ton* of warnings generated during the build and I'm not sure if they are important since the build completes without any errors and I can run whats there. Are there supposed to be lots of warnings generated during this process? and why the missing module?
Unfortunately it is no longer so easy. What you should do is check if the file has been modified in iReport (checking the isModified() in JrxmlEditorSupport). If it has not been modified, when the file is reloaded externally, no user prompt is displayed. If it is modified, force a jrxmlEditorSupport.saveDocument() and then make your changes.
giulio
Also just checked the 3.5.0 source vs 3.5.1. 3.5.0 doesn't have the jasperreports-components module. 3.5.1 binary distribution has the jar but its not in the source distribution anywhere. there are also two build.xml files in the main root of the 3.5.1 src project. there are several in other areas as well. perhaps this source distribution isnt correct?
I was able to successfully port my stuff to IR 3.5 after jumping thru some hoops: namely going back to release 3.5.0 source distro and setting up part of module in NB 6.01 since 6.7 was complaining that adding an option pane required NB platform 6.5+. The biggest problem right now is that I can't just distribute the module since I had to add a new data connection type to the IReportManager class.
But still happy I was able to get this stuff to work...
Hmm okay,
but how do I get the corresponding JrxmlEditorSupport when I just have a file???
Now I open the JRXML via the OpenCookie.... so I don't have any reference to the JrxmlEditorSupport .
I can't find a method in IReportManager where all open JrxmlEditorSupport instances are hold where I could get one by file.
Or is there any way to get a reference to the JrxmlEditorSupport when open a JRXML? Just by the OpenCookie it seems impossible.
(sorry for annoying you... but without documentation it's quite complicate to understand the new nb-version/logic)
regards again from still sunny Germany
C-Box
BTW: do I have to do something else after OpenCookie (see code below) to open a JRXML correct? I got the case, that I opened the file via code below and just change the foregroundcolor of an element --> then click on any place within the editor and I get "Externally modified. Reload it?" ..... so I haven't done anything after the openFileInIreport call within my plugin... just the color changement and yet iReport asks me to reload it? So I guess I'm doing something wrong or I missed something!??!
Code: |
public static void openFileInIreport(File file) throws Exception { if (file == null || !file.exists()) { return; } DataObject obj = DataObject.find(org.openide.filesystems.FileUtil.toFileObject(file)); OpenCookie ocookie = obj.getCookie(OpenCookie.class); if (ocookie != null) { ocookie.open(); } }</td></tr></tbody></table><br><br>Post Edited by CBox at 05/14/2009 15:23 |
Hi Giulio,
I'm still looking for a way to get to know whether a JRXML is already openend or not within iReport and I searched your code how the instances are hold (seems to be the task of some openide classes) -> unfortunately without success .
Could you please give me (us) some hints how to access opened files (not just the ActiveVisualView) from a plugin????
would be really nice
tia
C-Box
Hi again,
seems to become quite silent here....!?!??!
Because I'm still fighting against the new netbeans structure I came to a new question today...
I want to close openend files (see posts before with OpenCookie) by my plugin... so I made a closeaction at my tree and tried the code below... but this time it doesn't work... I don't get a CloseCookie...
So the new question is: How to close an opened JRXML just by FileName (java.io.File). ???
btw, for the other question concerning opened JRXMLs I still couldn't find any solution?!?
tia & hoping for any input
C-Box
Code: |
public static void closeFileInIreport(File file) throws Exception{ if (file == null || !file.exists()){ return; } DataObject obj = DataObject.find(org.openide.filesystems.FileUtil.toFileObject(file)); CloseCookie ccookie = obj.getCookie(CloseCookie.class); if (ccookie != null){ System.out.println("CloseCookie is da und macht nen Close!"); ccookie.close(); } }</td></tr></tbody></table> |
Hi again,
back from holiday I had the hope that someone could help me out, but unfortunately it seems that I'm the only one who is
a) developing an iReport Plugin for new nb-version or
b) too stupid to find the right methods to control iReport remotely.
So again... is there any way to get the opened JRXML editor frames to close them by a plugin? Also I must know whether a JRXML was opened already or not (to prevent annoying "Reload question")
I struggeld with CloseCookie... and just found tutorials how to write own Netbeans IDE based apps... but not plugins that just use the given logic from e.g. iReport 3.5.X.
Please Giulio, if you find two minutes to point me into the right direction or if you have a manual, how to develop a plugin... you would make me happy!
regards from sunny Germany
C-Box
Hi C-Box! How are you?
Here is a sample plugin that opens a view with the list of opened reports. You can select an item and close the document.
Hope it is what you need. Let me know if you don't understand the code.
To compile it, you need to install iReport inside the NetBeans version you are using since it uses the default platform and declares a dependency on the ireport-designer module (and to a bunch of other core modules).
Giulio
Hi there!
I developed an iReport plugin which works launching iReport inside the Netbeans Developer Studio.
Trying to deploy the nbm in a standalone iReport-Client fails...
It`s missing some dependencies which are available within Netbeans but not deployed to iReport...
I can't find any solution to get my plugin running.
Maybe someone here can give advices to me?
regards frank
Hi Giulio,
I'm fine thx for the question. Hope the same for you!??
Thx a lot for the nice code snipped... I didn't get it to work as module, as I still have NetBeans 6.0.1 and you dependecies requires new versions but I understood the code and I'm now able to close the files opened by my plugin. So you saved my summer and I can sleep better ( at least if Junior II is also sleeping between his breastfeedings ).
So I'm now just want to switch between openend files without reopening them (what I do now with simply OpenCookie.open() see code snippets in older post).
Is there a way to activate such a found JrxmlEditorSupport Component?
I already tried the "toFront" Method of the TopComponent. but it seems, it's not overriden in special for that purpose and just brings the whole (parent) window to front. (just as the apidoc tells).
public static void activateEditorByFile(File file) throws Exception{ DataObject seachFileObj = getDataObjectByFile(file); Set<TopComponent> components = Collections.synchronizedSet(new HashSet(WindowManager.getDefault().getRegistry().getOpened())); for (TopComponent t : components) { JrxmlEditorSupport jrxmlEditorSupport = t.getLookup().lookup(JrxmlEditorSupport.class); if (jrxmlEditorSupport != null) { DataObject editorFileObj = jrxmlEditorSupport.getDataObject(); if (editorFileObj.equals(seachFileObj)) { t.toFront(); break; } } } }
as I said: without success.
The code for STRG+TAB where you can easily change between opened docs seems to be within the core libs... so I can't take a look into the code how this is done.
The SHIFT + F4 also....
So... I don't want to reopen the files always if I navigate through my plugin, as iReport always ask if the external modified file should be reloaded. Would by glad, if you could help again.
regards from sunny Dresden /Saxony /Germany
C-Box
Hi Giulio big Guru,
I do have some troubles with the reload question of iReport that appears if the JRXML is changed externally,
The problem is, that when I load a JRXML via my plugin and save it back to database some verifications are done (field check, add some importdirective, check expression chunks and so on....)
This verification thread saves the JasperDesign back to JRXML and compiles this to a JasperFile and both (JRXML and JASPER) are saved in database finally.
So the file is changed outside iReport (but within my plugin) and even if there is nothing different (so when verify method has nothing changed) the question of reload pops up - but this is happen just if the JrxmlEditorSupportTopComponent is activated again. So if I still have an element selected I can change the Color (or any other attribute) of it, but when I then click into the editorpanel I get the question concerning reload caused by external changes (so this could happen even some minutes after the JRXML actually was verified&modified by plugin) - so it happens that some changes you made (especially complex expressions) are lost if the user activates the JrxmlEditorSupport Component later and answers "YES" to the reload-question.
So is there a chance to reload the jrxml by my plugin (right after it was saved in DataBase) to prevent that question???? Unfortunately "notifyUnmodified" or "reloadDocument" are protected inside the JrxmlEditorSupport.
Would be nice if you have a solution (again)
regards from today cloudy Germany
C-Box
gmasterb: this can be done with these steps:
1. Put your jars in the release/modules/ext directory inside your module (<your module project>/release/modules/ext)
2. For each jar, add this piece of xml to the project metadata (project.xml):
<class-path-extension>
<runtime-relative-path>ext/your_external.jar</runtime-relative-path>
<binary-origin>release/modules/ext/your_external.jar</binary-origin>
</class-path-extension>
The class-path-extension tags go immediatly after the tag </public-packages>
Restart netbeans to be sure the jars are loaded and available when coding.
CBox: You have full access to the JasperDesign, so it is not useful to load the jrxml again, changing it and saving the file by your self. Just get the JasperDesign from the editor support (jrxmlEditorSupport.getCurrentModel() ), any change should set the file in state "must be saved". In case it does not, add a fake report property and then remove it. Then just lookup for the SaveCookie and call saveCookie.save(). This is much better because it respects the compatibility settings requested by the user.
Giulio
Hi Guilio,
I did as you told and it seems to work. Now I pass the JasperDesign from JrxmlEditorSupport to my verifythread and just modify it.
I finally used the JrxmlEditorSupport.saveDocument() method. I guess it's the same as SaveCookie.save() ?
thx for your time, great work (as always)
regards from today sunny Germany
C-Box
Yes, it something similiar.
We store all designs and compiled objects in database for printing purpose within our ERP System.
Pictures and Fonts are also managed via the plugin and stored as we need it within EJB JBoss Appserver where no filesystem access is allowed.
So I guess JasperServer is something similiar but for normal reporting purpose... we build some logic behind our whole printing stuff. ( so different JRXMLs are reused between different functions to minimized design effort).
So the plugin migration is nearly done, now I just want to change the JR libs from 2.0.5 to 3.5.2 ones within our project and hope that it will work!!!!
have a nice day... till next question I'll surely have...
C-Box
Really cool! I think it is the typical iReport integration. I mean, it's a way to speed up a lot and integrate the report development.
As the new JasperBabylon is ready I'll provide a new tool to translate iReport in a simple way. Hope you'll be available to translate it in German a little bit...
Thanks!
Giulio
Hi Frank,
I use an ANT task to deploy the needed libs to iReport, so I do have some JAR's that I need withing the module (for developing the plugin) and some JAR's that the plugin & iReport needs at runtime (for verify & compiling & custom expressions).
Perhaps you find some hints where to put it. (the variable ireport.installdir is still hardcoded yet... and I need the old ireport-utils-2.0.5 to support the old barcode elements at least, that the user can change within new 3.5.2 iReport to new barcode component but won't get errors, if he doesn't )
hth
C-Box
Code: |
<target name="afpsReleaseToLocalIreport" depends="afpsPreparePluginWithLibs,jar"> <property name="ireport.installdir" value="D:/iReport/iReport-nb-3.5.2"/> <copy todir="${ireport.installdir}/ireport/modules/ext/" overwrite="true" failonerror="yes" preservelastmodified="true"> <fileset file="${afps.lib.tmp}/IBeeSCommon.jar"/> <fileset file="${afps.lib.tmp}/AfpsCommon.jar"/> <fileset file="${afps.server.home}/release/PrintDTOs.jar"/> <fileset file="${afps.lib.afps}/AfpsHttpClient.jar"/> <fileset file="${afps.lib.jasper}/iReport-utils-2.0.5.jar"/> </copy> <copy todir="${ireport.installdir}/ireport/config/modules/" overwrite="true" failonerror="yes" preservelastmodified="true"> <fileset file = "../build/cluster/config/Modules/${code.name.base.dashes}.xml"/> </copy> <copy todir="${ireport.installdir}/ireport/modules/" overwrite="true" failonerror="yes" preservelastmodified="true"> <fileset file = "../build/cluster/Modules/${code.name.base.dashes}.jar"/> </copy> </target></td></tr></tbody></table> |
Hi Giulio,
just send me an eMail if the JasperBabylon Tool (Plugin) is available and I'll do my best to find proper german translations!
One question came up yesterday....
If I change multiple designs and save the whole parent node (it's childs represent the Jrxmls of such a so called "print-template-set") I do call the JrxmlEditorSuppoer.saveDocument() method of each sub child node. I debugged it successfully and each node calls this method... (so nothing is skipped)
BUT the one that is active within iReport doesn't seem to get the flag "unmodified"... so even after the save call it's boolean method "isModified" returns true... but just the one which is active.
The other ones returns false... what is correct... so what could cause this and how can I avoid that. (it's kind of confusing the end user if he saves the design back to database but the node is still red what means "modified")
regards from again sunny Germany
C-Box
Hi Giulio,
I do have still some problems with the Opening of JRXML files...
now I do this:
....
DataObject obj = DataObject.find(org.openide.filesystems.FileUtil.toFileObject(sr.getFile())); OpenCookie ocookie = obj.getCookie(OpenCookie.class); if (ocookie != null) { System.out.println("OpenCookie is da und macht nen Open!"); ocookie.open(); editor = getIReportFrameByFile(sr.getFile()); if (editor != null) { sr.setEditor(editor); } }
....
where getIReportFrameByFile(File file) makes this:
private static JrxmlEditorSupport getIReportFrameByFile(File file) throws Exception { DataObject dataObj = getDataObjectByFile(file); Set<TopComponent> components = Collections.synchronizedSet(new HashSet<TopComponent>(WindowManager.getDefault().getRegistry().getOpened())); for (TopComponent t : components) { JrxmlEditorSupport jrxmlEditorSupport = t.getLookup().lookup(JrxmlEditorSupport.class); if (jrxmlEditorSupport != null) { DataObject editorFileObj = jrxmlEditorSupport.getDataObject(); if (editorFileObj.equals(dataObj)) { return jrxmlEditorSupport; } } } return null; }
The Problem is, that when I want to get the JasperDesign rigjht after opening the file - the methode getCurrentModel returns null and not the model of the JRXML.. as expected......
....
if (sr.getEditor() != null) { JasperDesign design = sr.getEditor().getCurrentModel(); if (design == null) {
<span style="color: rgb(255, 0, 0);"><b>// here I always get null although the file was opened and I successfully got an editor....</b></span> return; } // neue Felder gleich an dieser Stelle refreshen! VerifierUtil.refreshFieldsByPrintDTO(design); }
....
When I debugged the "setCurrentModel" of JrxmlEditorSupport I noticed that this is probably just called if the JrxmlVisualView is shown... (at componentShowing or within the run thread method....)
So is there another way to open a file to get the JasperDesign right afterwards ? Of course I could load the design via JrxmlLoader but when I changed this object the changes arent visible when the JrxmlVisualView is activated (as another design object is loaded).
any ideas would be great!
regards from VERY hot Germany
C-Box
Hi C-Box,
I faced the same problem with the JasperServer plugin when I load an image referenced in the report from the repository.
You get null because the jrxml is loaded in a different thread and may take few milliseconds, you are calling the getModel too fast.
Here is the solution I adopted (you can find the code for reference in the JasperServer plugin, it is a module of iReport). I created a listener (JrxmLookupListener) that extends LookupListener and I use it as follow:
DataObject obj = DataObject.find(FileUtil.toFileObject(new File(fname)));
OpenCookie ocookie = obj.getCookie(OpenCookie.class);
if (ocookie != null)
{
ocookie.open();
RepositoryReportUnit reportUnit = ReportUnitNode.getParentReportUnit(node);
// Add temporary info about where this jd comes from...
JasperServerManager.getMainInstance().getJrxmlReportUnitMap().put(fname , reportUnit);
if (rf.getDescriptor().getWsType().equals( ResourceDescriptor.TYPE_JRXML))
{
JrxmLookupListener listener = new JrxmLookupListener(obj, jrxmlListeners, reportUnit, rf.getServer());
jrxmlListeners.add(listener);
}
}
The listener listen to the DataObject lookup. When the JasperDesign is loaded, it is put in the DataObject lookup, and you can get it from there or using the JrxmlEditorSupport, it's the same thing.
Giulio
Hi anyone,
Hi giulio,
I am having problom to install nbm plugin into iReport standalone, I follow your step, but iReport still asking for jar dependency. I attach the nbm and project.xml.
I folow these steps:
1. Put your jars in the release/modules/ext directory inside your module (<your module project>/release/modules/ext) 2. For each jar, add this piece of xml to the project metadata (project.xml): The class-path-extension tags go immediatly after the tag </public-packages>
<class-path-extension>
<runtime-relative-path>ext/your_external.jar</runtime-relative-path>
<binary-origin>release/modules/ext/your_external.jar</binary-origin>
</class-path-extension>
And then, I create the nbm file, and I try to install this nbm plugin into iReport standalone, but iReport still asking for jar dependency.
Please help, thanks a lot.
Arie
Code: |
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://www.netbeans.org/ns/project/1"> <type>org.netbeans.modules.apisupport.project</type> <configuration> <data xmlns="http://www.netbeans.org/ns/nb-module-project/3"> <code-name-base>org.company.reportlogin</code-name-base> <standalone/> <module-dependencies> <dependency> <code-name-base>org.openide.dialogs</code-name-base> <build-prerequisite/> <compile-dependency/> <run-dependency> <specification-version>7.10.1</specification-version> </run-dependency> </dependency> <dependency> <code-name-base>org.openide.util</code-name-base> <build-prerequisite/> <compile-dependency/> <run-dependency> <specification-version>7.22.1.1</specification-version> </run-dependency> </dependency> </module-dependencies> <public-packages/> <class-path-extension> <runtime-relative-path>ext/org-openide-dialogs.jar</runtime-relative-path> <binary-origin>release/modules/ext/org-openide-dialogs.jar</binary-origin> </class-path-extension> <class-path-extension> <runtime-relative-path>ext/org-openide-util.jar</runtime-relative-path> <binary-origin>release/modules/ext/org-openide-util.jar</binary-origin> </class-path-extension> </data> </configuration> </project> </td></tr></tbody></table> |