0

Using the tutorial of Creating Java control in an NSF, I was able to create a simple Java control. Now I want to extend it so that it displays an image so I modified the code in following way:

This is the example control class which now extends the UIGraphicEx class instead of UIComponentBase.

package com.example.component;
import com.ibm.xsp.component.UIGraphicEx;
public class ExampleControl extends UIGraphicEx {
    public ExampleControl() {
        super();
        setRendererType("com.ibm.xsp.ImageEx");

    }
    @Override
    public String getFamily() {
        return "com.example.examplecontrol";
    }
}

This is the xsp-config file for example control class defined above. I have modified it by adding <base-component-type> with value as com.ibm.xsp.component.UIGraphicEx and set <renderer-type> to com.ibm.xsp.ImageEx.

<faces-config>
    <faces-config-extension>
        <namespace-uri>http://example.com/xsp/control</namespace-uri>
        <default-prefix>eg</default-prefix>
    </faces-config-extension>
    <component>
        <description>Example</description>
        <display-name>Example Control</display-name>
        <component-type>com.example.examplecontrol</component-type>
        <component-class>com.example.component.ExampleControl</component-class>
        <component-extension>
            <base-component-type>com.ibm.xsp.component.UIGraphicEx</base-component-type>
            <component-family>com.example.examplecontrol</component-family>
            <renderer-type>com.ibm.xsp.ImageEx</renderer-type>
            <tag-name>exampleControl</tag-name>
            <designer-extension>
                <category>Example</category>
                <selected-event>onclick</selected-event>
            </designer-extension>
        </component-extension>
    </component>
</faces-config>

My renderer class looks like this. Here instead of using ResponseWriter class, I am casting the UIComponent object to UIGraphicEx and setting its URL (the image is present in the same database).

package com.example.renderkit.html_basic;
import javax.faces.render.Renderer;
import java.io.IOException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import com.ibm.xsp.component.UIGraphicEx;
public class ExampleRenderer extends Renderer {
    @Override
    public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
        UIGraphicEx g = (UIGraphicEx)component;
        g.setUrl("review_icon.gif");
        g.setRendered(true);
        System.out.println("-----------" + g.getUrl());
    }
    @Override
    public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
    }
}

When I put this control in XPage no output is given, however the System.out.println statement in method encodeBegin fires up in the console. What am I doing wrong here? Is this the correct way to proceed?

My final objective here is to generate image data on the fly (based on some input) and then put it into image control through the renderer. How can I achieve that?

Naveen
  • 6,786
  • 10
  • 37
  • 85
  • 1
    Do you want to render a graphic image in the XPage? Have a look at the Barcode plugin on OpenNTF. http://www.openntf.org/internal/home.nsf/project.xsp?action=openDocument&name=XPages%20Barcode%20Control – Simon O'Doherty Aug 21 '12 at 21:56
  • Thanks Simon. You pointed me towards the exact direction. But your Barcode control uses Base64 string for the image. My image would be more complex so converting them to Base64 would not be a good idea. Also my images would be generated using XAgent with XPage. I can put the XPage path in `src` but how can I put the XPage in the Java Control? Is there any alternate way to do this? – Naveen Aug 22 '12 at 17:36
  • Well the base64 conversion is so that that the IMG tag can render it inline. So if it is a static image to the end user, it should be fine for what you need. Or do you need the users to modify the graphics? If so have a look into the HTML5 canvas. – Simon O'Doherty Aug 22 '12 at 21:00

2 Answers2

1

Be sure to ensure that the family is defined the same in the component, xsp-config and faces-config. Also, as Toby said, you're not writing anything out to the ResponseWriter. You need to output some html to the screen using ResponseWriter. Or, if you're just wanting to output the exact same thing as the UIGraphicEx renderer, make your renderer extend it (UIGraphicEx Renderer class) and call super.encodeBegin() and super.encodeEnd().

package com.example.renderkit.html_basic;
import javax.faces.render.Renderer;
import java.io.IOException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import com.ibm.xsp.component.UIGraphicEx;
public class ExampleRenderer extends Renderer {
    @Override
    public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
        UIGraphicEx g = (UIGraphicEx)component;
        g.setUrl("review_icon.gif");
        g.setRendered(true);
        ResponseWriter writer = context.getResponseWriter();
        writer.append("<img src='http://someserver/somedb.nsf/review_icon.gif' />");
        System.out.println("-----------" + g.getUrl());
    }
    @Override
    public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
    }

}

keithstric
  • 1,053
  • 1
  • 11
  • 21
  • Your solution works, but in my case the image is going to be generated on the fly. Simon O'Doherty put in a comment suggesting me to look at Barcode control (http://www.openntf.org/internal/home.nsf/project.xsp?action=openDocument&name=XPages%20Barcode%20Control) which uses Base64 string for the image. My image would be more complex so converting them to Base64 would not be a good idea. Also my images would be generated using XAgent with XPage. I can put the XPage path in src but how can I put the XPage in the Java Control? Is there any alternate way to do this? I know its a bit complicated :) – Naveen Aug 22 '12 at 17:40
  • Maybe add it as an iFrame? Dunno, never done that sort of thing. Or, get the image from the XAgent as a BufferedImage and then save it temporarily to disk or something to that effect. You might/might not get some ideas from this post on my blog http://xprentice.gbs.com/A55BAC/keithstric.nsf/default.xsp?documentId=B69A5A4E460E3D4185257A360051B9B8 – keithstric Aug 23 '12 at 16:57
0

EDIT: You can't wrap up an xagent and deploy it serverwide. I would suggest using a servlet and deploy it via an OSGI plugin.

Toby Samples
  • 2,168
  • 14
  • 15
  • I tried adding your code and it throws error `javax.servlet.ServletException: java.lang.StackOverflowError`. I added the code like this: `g.encodeBegin(context); g.setUrl("review_icon.gif"); g.encodeEnd(context);` – Naveen Aug 21 '12 at 17:40
  • Yes after re-looking at my answer it won't work, Can you give a better description of what you are wanting to render? How are you wanting this component to be different than UIGraphicEx – Toby Samples Aug 21 '12 at 18:31
  • I am planning to use a XAgent in XPage to generate the image data and then put that in the `src` attribute. My image would be created on the fly. I can put the XPage path in `src` but how can I put the XPage in the Java Control? Is there any alternate way to do this? – Naveen Aug 22 '12 at 17:42
  • I'm not sure what you mean, In the past I've used an Xagent to write image/jpeg data to the response writer, I've just been able to put the xpage path in the src attribute. Are you wanting to add other variables or something? – Toby Samples Aug 22 '12 at 17:53
  • I have an XPage (XAgent) which generates image data and which I put in the `src` attribute in my Image on XPage. It works fine. Now I intend to make it a Java control and to deploy it on server and designer. But I don't think I would be able to package the XPage (XAgent) in the Java control. Or can I? Basically my image is to be generate on the fly with inputs from user. So for e.g. lets say user wants a blue circle in image I would be generating the image and rendering it through Java control. – Naveen Aug 23 '12 at 04:54
  • 1
    No, you can't really do that with an xagent, however I would recommend instead of using an Xagent, you could build a Servlet to return the image. To do a real servlet check out this video from Niklas Heidloff http://www.openntf.org/blogs/openntf.nsf/d6plinks/NHEF-8JB9DN. Then you could package it as an osgi plugin on your domino server. – Toby Samples Aug 23 '12 at 13:13
  • Yes servlets seem to be a best approach in my case. I saw the video by Niklas and trying to incorporate in my eclipse. So far unsuccessful. The article explains the basic but doesn't seem to shed any light on how to get everything running on Eclipse. If you have any link/resource to for creating servlet as OSGi bundle for Domino on eclipse do tell me. I would be happy to accept this answer if you edit it to this one.. :) – Naveen Aug 26 '12 at 12:21
  • I updated the answer, I would look at the presentation from Show n tell 110 from lotusphere 2012 if you can get a hold of it. – Toby Samples Aug 27 '12 at 13:15