How to implement custom JSF component for drawing chart? - java

I want to create a component which can be used like:
<mc:chart data="#{bean.data}" width="200" height="300" />
where #{bean.data} returns a collection of some objects or chart model object or something else what can be represented as a chart (to put it simple, let's assume it returns a collection of integers).
I want this component to generate html like this:
<img src="someimg123.png" width="200" height="300"/>
The problem is that I have some method which can receive data and return image, like:
public RenderedImage getChartImage (Collection<Integer> data) { ... }
and I also have a component for drawing dynamic image:
<o:dynamicImage width="200" height="300" data="#{bean.readyChartImage}/>
This component generates html just as I need but it's parameter is array of bytes or RenderedImage i.e. it needs method in bean like this:
public RenderedImage getReadyChartImage () { ... }
So, one approach is to use propertyChangedListener on submit to set data (Collection<Integer>) for drawing chart and then use <o:dynamicImage /> component. But I'd like to create my own component which receives data and draws chart.
I'm using facelets but it's not so important indeed. Any ideas how to create the desired component?
P.S. One solution I was thinking about is not to use <o:dynamicImage/> and use some servlet to stream image. But I don't know how to implement that correctly and how to tie jsf component with servlet and how to save already built chart images (generating new same image for each request can cause performance problems imho) and so on..

P.S. One solution I was thinking about is not to use and use some servlet to stream image. But I don't know how to implement that correctly and how to tie jsf component with servlet and how to save already built chart images (generating new same image for each request can cause performance problems imho) and so on..
Just give it an URL as attribute so that it ends up as <img src="url"> and let that URL point to the servlet. Let the servlet generate/return the image based on the information provided by request parameters or pathinfo in the URL.
As to the caching, just store it somewhere in the disk file system or a DB by some unique identifier and let the servlet on every request check if it is there and handle accordingly.
For this all the standard <h:graphicImage> would be already sufficient. Just make the URL dynamic.

Related

display an image from server with an output stream

I am trying to show an image from the server in my browser.I am following this link
http://balusc.blogspot.in/2007/04/imageservlet.html. i must say this is pretty well written and documented. I tried this and everything is working fine.
The problem is there when i am using ajax to display this image.the whole image seems to break into some codes inside the div.
i understand that the outputstream used in the code is writing directly to the page.But is it really not possible to handle that outputstream to somehow display the image in image tag of a jsp without having to create a different servlet.
Thank you for reading
You don't need to request image data via AJAX and then manipulate it yourself, in order to display it. Just use an <img> tag!
If /my_url is the location of your image, then
<img src="/my-url" alt="Appropriate description"/>
would do it. NOTE: /my-url doesn't have to be an actual image. It can be any resource (including a servlet) that returns image data with the appropriate MIME type set.
If you want to create the tag dynamically, you can use your favourite library, or do it iwth native JS:
var oImg=document.createElement("img");
oImg.setAttribute('src', '/my-url');
oImg.setAttribute('alt', 'Appropriate description');
oImg.setAttribute('height', imgHeight);
oImg.setAttribute('width', imgWidth);
document.body.appendChild(oImg);
Edit
If you want to be doing this server-side (and if so, is this really AJAX?), then you might want to look at the data uri scheme.
With this scheme, you can data directly to an image tag, without needing to provide it with an HTTP resource. To use this, you convert your outputstream to base64 and use the following:
<img src="data:image/png;base64,converted-data-stream-goes-here..." alt="Who needs HTTP?"/>
The image/png would change depending on the MIME type of your source data.
Read the linked Wikipedia page to fully understand the trade-offs here.
Just adding how i achieved a solution for it.
I referred to a new page(from the page i am submitting the form) through ajax and in the new page i used an image and through its src attribute i called the servlet method which is writing the image through its outputstream.
This way the servlet is writing my image to the new file which i can position anywhere.

How to render parts of form from ActionListener in JSF

I have a simple file upload mechanism in one of my jsf pages. Once the file has been uploaded, I have an ActionListener that fires. At this point, I have access to the name of the file that the user uploaded, and I want to add this to an outputText component. How can I re-render the form from java code so that the file is displayed? Can I call some ajax function?
/**
* Called when a file is uploaded
* #param event The FileUploadEvent that contains info on the file uploaded
*/
public void handleFileUpload(FileUploadEvent event){
data = event.getFile().getContents();
name = event.getFile().getFileName();
}
Above is the code that runs once the file has been uploaded. You can see I get the name of the file. I need now to re-render the outputText so that the name is displayed.
This is usually to be declared in the view side.
Even though you didn't mention anything about it (which is bad; you should always mention in the question which JSF implementation and component libraries exactly you're using and for sure not overgeneralize everything as "standard JSF"), the listener method code which you've there is recognizeable as the one specific to PrimeFaces <p:fileUpload>.
In that case, you should actually be using component's own update attribute which should reference the (relative) client ID of the component you'd like to update on complete of the ajax request.
<p:fileUpload ... update="text" />
...
<h:outputText id="text" value="#{bean.text}" />
That's all. You'd in this particular example just have to assign the filename to the text property.
See also:
<p:fileUpload> VDL documentation — lists all available attribtues.

How can I include a JFreeChart servlet image in a JSP

I have seen several examples of using a Servlet to dynamically generate a chart using JFreeChart, and subsequently including that image in a JSP using an img tag. For example:
<img src="/MyChartServlet" width="400" height="300" border="0" alt="" />
My servlet which generates the image using JFreeChart works great, and I can see the image if I call it directly in the browser as in:
http:/myurl/MyChartServlet?id=274
The problem is that my JSP does not display the image. In fact, the JSP is not even invoking the servlet. I know this because I do not see the debug entries in the log that appear when the servlet is called.
In the Servlet I am using the JFreeChart ChartUtilities.writeChartAsJPEG() method to write the image to the output stream of the response, because I do not want to write the image to disk. As mentioned the servlet works fine when called directly.
What am I missing? Or is there a better way to do this? Maybe a plain old object can generate the chart and I can include that in the JSP? Any help would be appreciated.
You're going about it the right way. You may be having some kind of relative path issue from the context you're in. Try
<img src="http://<full path to your servlet>" ...
Also, you have a ?id=274 in your example, but not in your img src. If that's required, put that in there as well.
If you posted your servlet code, that could help, but also make sure you have your content type set properly in your servlet
response.setContentType("image/jpeg");

Updating the url bar from the webapp to represent the current state

I would like to basically do what Jason asked for here
In one sentence, I would like the url bar to represent the state of the AJAX application so that I can allow to bookmark it as well as allow the user to return to the previous state by using the back/forward buttons in the browser.
The difference for me (From what Jason asked) is that I am using JSF 2.0.
I've read that JSF 2.0 added the ability to use get, but I am not sure what the correct way to use this.
Thanks for the help.
Further Clarification
If I understand correctly, to be able to bookmark specific states in the AJAX webapp I will have to use the location.hash. Am I correct? I'm trying to achieve a gmail-like behaviour in the sense that, while the app is complete AJAXified and no redirects occur, I can still use Back/Forward and bookmark (And that's why I would like the URL bar to be updated from the AJAX app itself and not through redirection)
Update
Just found this similar question
The difference for me (From what Jason asked) is that I am using JSF 2.0. I've read that JSF 2.0 added the ability to use get, but I am not sure what the correct way to use this.
Please note that this is not the same as maintaining the Ajax state. It usually happens by fragment identifiers (the part starting with # in URL, also known as hashbang). JSF doesn't offer builtin components/functionality for this. As far I have also not seen a component library which does that. You may however find this answer useful to get started with a homegrown hash fragment processor in JSF.
As to using GET requests, just use <h:link>, <h:outputLink> or even <a> to create GET links. You can supply request parameters in the h: components by <f:param>. E.g.
<h:link value="Edit product" outcome="product/edit">
<f:param name="id" value="#{product.id}" />
</h:link>
In the product/edit.xhtml page you can define parameters to set and actions to execute upon a GET request
<f:metadata>
<f:viewParam name="id" value="#{productEditor.id}" />
<f:event type="preRenderView" listener="#{productEditor.init}" />
</f:metadata>
In the request or view scoped bean associated with product/edit.xhtml page -in this example #{productEditor}-, you just define the properties and the listener method. The listener method will be executed after all properties are been gathered, converted, validated and updated in the model.
private Long id;
private Product product;
public void init() {
product = productService.find(id);
}
Normally you'd use AJAX to prevent complete page refreshes. AFAIK all current browsers would issue a page refresh if you change the base uri. Thus you would have to use the hash part as suggested in the question you provided.
We had a similar problem and did something like this:
We settled for the fact that users cannot bookmark the url.
For URLs that should be unique/bookmarkable we used different links that issue a redirect. Those URLs are provided in a sitemap.
For browser back, we added an intermediate page after login. This page does navigation and a redirect to the application. The navigation is stored in the session and when the server gets a navigation request (which can be a history back) the corresponding state is restored. A browser back opens that intermediate page which issues a redirect along with a navigation request on the server side.

What are all the changes we have to do in JqGrid, incase of using DWR & java instead of AJAX & PHP?

First, i have to declare myself that, i dont know PHP & AJAX. I know something in DWR, javaScript & java, like i am able to create a Web based CRUD by using them. I want to integrate DWR & JAVA with the jQGrid. I did a lot of research for that. I am not able to find anything that uses JAVA & DWR in jqGrid.
Any conceptual idea or solution will be appreciative.
Any online links will be more appreciative.
Thanks in advance.
You asked about conceptual idea of a possible solution. I try shortly describe a possible way. How I could understend from your previous question you are a beginner in JavaScript and jQuery. So I try to write simple and clear describe the arcitectur of the solution.
Your Web application can consist of pure HTML or XHTML pages (without any JSP pages) with Javascript files loaded and started throght <script type="text/javascript" src="..."></script>. You place HTML/XHTML markup in your *.htm files and the definition of jqGrid in *.js files.
jqGrid has three important parameter mtype which are typically "GET" or "POST", datatype withe the values like "xml" or "json" and url parameter. This three parameters defins how the grid will be filled. There are also editurl cwich are used for CRUD operations. So you can implement a servlet in Java (see How to learn AJAX using jQuery in a Java web app for example) which could be the only active component in your solution which bound to the URL defined by url and editurl and support HTTP GET or POST depend of your mtype choice. It will work like a web service which provide the data for the jqGrids and implement all CRUD operations.
jqGrid will send to servlet some standard parameters. The names of this input parameters of the servlet you can change with prmNames parameter of jqGrid (see http://www.trirand.com/jqgridwiki/doku.php?id=wiki:options). The most important parameters of the servlet method are following int page, int rows, string sidx, string sord. Adfditional parameters could be also bool _search, string searchField, string searchOper, string searchString if you want to use single searching in th jqGrid or bool _search, string filters in case of advanced searching. So it user click on the "next page" jqGrid button or click on the grids column header to sort the data, your servlet will by called by jqGrid with the corresponding values of the imput parameters.
In the way you have clear structure of your solution. I am not sure that you will need DWR. Just try to find how you can use jQuery.ajax to call your Java servlets. If you will have some problems with implemented the same technique inside of jqGrid you can customize jQuery.ajax requests which will be send by jqGrid with ajaxGridOptions jqGrid parameter. You can also use serializeGridData event of jqGrid (see http://www.trirand.com/jqgridwiki/doku.php?id=wiki:events#list_of_events) to implement any data conevrsion before the data will be snd to the servlet and use use jsonReader or xmlReader (see http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data) which define how the data returned from the server should be readed by jqGrid.

Categories

Resources