Signature Bean

Hi Everyone,

I am trying to adapt some of the logic from this signature capture java applet [http://www.planet-source-code.com/URLSEO/vb/scripts/ShowCode!asp/txtCodeId!110/lngWid!9/anyname.htm] into a bean that is usable with servoy. However, when I create the jar file and place it in the beans directory, and restart the repository, it doesn’t show up on my list of beans. I take it there is something wrong with my code but I have no idea what it is – if someone who has experience writing beans could take a look at it I would appreciate it.

Manifest File

Name: Signature.class
Java-Bean: True

Signature.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.coh.signature;

/**
 *
 * @author jsharp
 */
// Signature Capture Class 

//import java.awt.event.*;

import java.awt.event.MouseEvent;
import java.io.Serializable;
import com.servoy.j2db.scripting.IScriptObject;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.Vector;

    
public class Signature extends Canvas implements MouseListener, MouseMotionListener, Serializable, IScriptObject {    
    Vector<Rectangle> lines = new Vector<Rectangle>();    
    transient Integer x1,y1;
    transient Integer x2,y2;    
    transient Integer clearflag=0;
    Integer appwidth=300;
    Integer appheight=75;
    Integer delta=15;
    Integer lock=0;

    public Signature() {
	//setBackground(new Color(255,255,191));			
	setBackground(Color.white);			
	addMouseMotionListener(this);
	addMouseListener(this);	
    }

    
/*    public Vector<Rectangle> getLines() {
      return lines;
    }

    public void setLines(Vector<Rectangle> l) {
	lines.clear();
      lines.setSize(l.size());
	Collections.copy(lines, l);
    }
*/
    
    public Integer js_getLocked() {
	return lock;
    }

    public void js_setLocked(Integer l) {
	lock = l;
    }

    public Integer getLocked() {
	return lock;
    }

    public void setLocked(Integer l) {
	lock = l;
    }
    
    public void js_setAppwidth(Integer w) {
	appwidth = w;
    }

    public Integer js_getAppwidth() {
	return appwidth;
    }

    public void setAppwidth(Integer w) {
	appwidth = w;
    }

    public Integer getAppwidth() {
	return appwidth;
    }

    public void js_setAppheight(Integer h) {
	appheight = h;
    }

    public Integer js_getAppheight() {
	return appheight;
    }

    public void setAppheight(Integer h) {
	appheight = h;
    }

    public Integer getAppheight() {
	return appheight;
    }
    
    public void js_setDelta(Integer d) {
	delta = d;
    }

    public Integer js_getDelta() {
	return delta;
    }
    
    public void setDelta(Integer d) {
	delta = d;
    }

    public Integer getDelta() {
	return delta;
    }

    public String js_getLines() {
        return getLines();
    }

    public void js_setLines(String dc) {
        setLines(dc);
    }

    public String getLines() {
    	Integer np=lines.size();
    	if (np==0){return "";}
    	String temp="";    	
    	for (Integer i=0; i < np; i++) {
	         Rectangle p = (Rectangle)lines.elementAt(i);
	         temp=temp + p.x + ",";
	         temp=temp + p.y + ",";	         
	         temp=temp + p.width + ",";
	         temp=temp + p.height + ",";
	    }   	    
	    temp = temp.substring(0,temp.length()-1);
	    return temp;
    }

    public void setLines(String dc) {
        try{                
        String [] coords = dc.split(",");
        Integer w,x,y,z=0;
        lines.clear();
        repaint();
        for (Integer i=0; i < coords.length;i=i+4) {              
            w = Integer.parseInt(coords[i]);
            x = Integer.parseInt(coords[i+1]);
            y = Integer.parseInt(coords[i+2]);
            z = Integer.parseInt(coords[i+3]);
            lines.addElement(new Rectangle(w,x,y,z));
        }        
        coords=null;
	    repaint();
	    }	    
	    catch (Exception e)	{}
    }
    
public void js_clear(){
	lines.clear();
	repaint();
}

public void clear(){
	lines.clear();
	repaint();
}


    public void mouseDragged(MouseEvent e) {
        e.consume();        
        if (lock==1) {return;}
        lines.addElement(new Rectangle(x1, y1, e.getX(), e.getY()));        
        x1 = e.getX();
        y1 = e.getY();         
        repaint();
    }
    public void mouseMoved(MouseEvent e) {    	            
	}
    
    public void mousePressed(MouseEvent e) {
        e.consume();        
        if (lock==1) {return;}
        lines.addElement(new Rectangle(e.getX(), e.getY(), -1, -1));
        x1 = e.getX();
        y1 = e.getY();
        repaint();        
    }
    public void mouseReleased(MouseEvent e) {        
    }
    public void mouseEntered(MouseEvent e) {    	        
    }
    public void mouseExited(MouseEvent e) {
    }
    public void mouseClicked(MouseEvent e) {
    	e.consume();
    if (lock==1) {return;}
    if (e.getX()>3 && e.getX()<13 && e.getY()>3 && e.getY()<13) {		
		clearflag=1;
		repaint();        
		}
    }
        
    @Override
    public void paint(Graphics g) {
	Integer np;	
	g.setColor(getBackground());
	if (clearflag==1){
		clearflag=0;
		lines.clear();
	}	
	np = lines.size();			        
	g.setColor(getForeground());
	g.drawLine(0,0,0,delta);
	g.drawLine(0,0,delta,0);
	g.drawLine(appwidth,0,appwidth-delta,0);
	g.drawLine(appwidth,0,appwidth,delta);
	g.drawLine(0,appheight,0,appheight-delta);
	g.drawLine(0,appheight,delta,appheight);
	g.drawLine(appwidth,appheight,appwidth,appheight-delta);
	g.drawLine(appwidth,appheight,appwidth-delta,appheight);	
		
	try {
		Font f = new Font("Monotype Corsiva",Font.ITALIC,64);
	    g.setFont(f);	
	}
	catch (Exception e) {}
	
	g.setColor(new Color(230,230,230));
	g.drawString("Signature",20,52);
	g.setColor(Color.red);
	g.drawRect(3,3,10,10);
	g.drawLine(3,3,13,13);
	g.drawLine(3,13,13,3);
	g.setColor(Color.black);
	
	for (Integer i=0; i < np; i++) {
	    Rectangle p = (Rectangle)lines.elementAt(i);
	    g.setColor(Color.black);
	    if (p.width != -1) {
		g.drawLine(p.x, p.y, p.width, p.height);
	    } else {
		g.drawLine(p.x, p.y, p.x, p.y);
	    }	     
	}		
}   

	public Class[] getAllReturnedTypes()
	{
		return null;
	}

	public String[] getParameterNames(String methodName)
	{
		return null;
	}

	public String getSample(String methodName)
	{
		return null;
	}

	public String getToolTip(String methodName)
	{
		return null;
	}

	public boolean isDeprecated(String methodName)
	{
		return false;
	}

}

SignatureBeanInfo.java [auto-generated with netbeans]

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.coh.signature;

import java.beans.*;

/**
 * @author jsharp
 */
public class SignatureBeanInfo extends SimpleBeanInfo {

    // Bean descriptor//GEN-FIRST:BeanDescriptor
    /*lazy BeanDescriptor*/
    private static BeanDescriptor getBdescriptor(){
        BeanDescriptor beanDescriptor = new BeanDescriptor  ( org.coh.signature.Signature.class , null ); // NOI18N//GEN-HEADEREND:BeanDescriptor

    // Here you can add code for customizing the BeanDescriptor.

        return beanDescriptor;     }//GEN-LAST:BeanDescriptor


    // Property identifiers//GEN-FIRST:Properties
    private static final int PROPERTY_allReturnedTypes = 0;
    private static final int PROPERTY_appheight = 1;
    private static final int PROPERTY_appwidth = 2;
    private static final int PROPERTY_delta = 3;
    private static final int PROPERTY_lines = 4;
    private static final int PROPERTY_locked = 5;

    // Property array 
    /*lazy PropertyDescriptor*/
    private static PropertyDescriptor[] getPdescriptor(){
        PropertyDescriptor[] properties = new PropertyDescriptor[6];
    
        try {
            properties[PROPERTY_allReturnedTypes] = new PropertyDescriptor ( "allReturnedTypes", org.coh.signature.Signature.class, "getAllReturnedTypes", null ); // NOI18N
            properties[PROPERTY_appheight] = new PropertyDescriptor ( "appheight", org.coh.signature.Signature.class, "getAppheight", "setAppheight" ); // NOI18N
            properties[PROPERTY_appwidth] = new PropertyDescriptor ( "appwidth", org.coh.signature.Signature.class, "getAppwidth", "setAppwidth" ); // NOI18N
            properties[PROPERTY_delta] = new PropertyDescriptor ( "delta", org.coh.signature.Signature.class, "getDelta", "setDelta" ); // NOI18N
            properties[PROPERTY_lines] = new PropertyDescriptor ( "lines", org.coh.signature.Signature.class, "getLines", "setLines" ); // NOI18N
            properties[PROPERTY_locked] = new PropertyDescriptor ( "locked", org.coh.signature.Signature.class, "getLocked", "setLocked" ); // NOI18N
        }
        catch(IntrospectionException e) {
            e.printStackTrace();
        }//GEN-HEADEREND:Properties

    // Here you can add code for customizing the properties array.

        return properties;     }//GEN-LAST:Properties

    // EventSet identifiers//GEN-FIRST:Events

    // EventSet array
    /*lazy EventSetDescriptor*/
    private static EventSetDescriptor[] getEdescriptor(){
        EventSetDescriptor[] eventSets = new EventSetDescriptor[0];//GEN-HEADEREND:Events

    // Here you can add code for customizing the event sets array.

        return eventSets;     }//GEN-LAST:Events

    // Method identifiers//GEN-FIRST:Methods
    private static final int METHOD_clear0 = 0;
    private static final int METHOD_getParameterNames1 = 1;
    private static final int METHOD_getSample2 = 2;
    private static final int METHOD_getToolTip3 = 3;
    private static final int METHOD_isDeprecated4 = 4;
    private static final int METHOD_js_clear5 = 5;
    private static final int METHOD_js_getAppheight6 = 6;
    private static final int METHOD_js_getAppwidth7 = 7;
    private static final int METHOD_js_getDelta8 = 8;
    private static final int METHOD_js_getLines9 = 9;
    private static final int METHOD_js_getLocked10 = 10;
    private static final int METHOD_js_setAppheight11 = 11;
    private static final int METHOD_js_setAppwidth12 = 12;
    private static final int METHOD_js_setDelta13 = 13;
    private static final int METHOD_js_setLines14 = 14;
    private static final int METHOD_js_setLocked15 = 15;
    private static final int METHOD_mouseClicked16 = 16;
    private static final int METHOD_mouseDragged17 = 17;
    private static final int METHOD_mouseEntered18 = 18;
    private static final int METHOD_mouseExited19 = 19;
    private static final int METHOD_mouseMoved20 = 20;
    private static final int METHOD_mousePressed21 = 21;
    private static final int METHOD_mouseReleased22 = 22;
    private static final int METHOD_paint23 = 23;

    // Method array 
    /*lazy MethodDescriptor*/
    private static MethodDescriptor[] getMdescriptor(){
        MethodDescriptor[] methods = new MethodDescriptor[24];
    
        try {
            methods[METHOD_clear0] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("clear", new Class[] {})); // NOI18N
            methods[METHOD_clear0].setDisplayName ( "" );
            methods[METHOD_getParameterNames1] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("getParameterNames", new Class[] {java.lang.String.class})); // NOI18N
            methods[METHOD_getParameterNames1].setDisplayName ( "" );
            methods[METHOD_getSample2] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("getSample", new Class[] {java.lang.String.class})); // NOI18N
            methods[METHOD_getSample2].setDisplayName ( "" );
            methods[METHOD_getToolTip3] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("getToolTip", new Class[] {java.lang.String.class})); // NOI18N
            methods[METHOD_getToolTip3].setDisplayName ( "" );
            methods[METHOD_isDeprecated4] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("isDeprecated", new Class[] {java.lang.String.class})); // NOI18N
            methods[METHOD_isDeprecated4].setDisplayName ( "" );
            methods[METHOD_js_clear5] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("js_clear", new Class[] {})); // NOI18N
            methods[METHOD_js_clear5].setDisplayName ( "" );
            methods[METHOD_js_getAppheight6] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("js_getAppheight", new Class[] {})); // NOI18N
            methods[METHOD_js_getAppheight6].setDisplayName ( "" );
            methods[METHOD_js_getAppwidth7] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("js_getAppwidth", new Class[] {})); // NOI18N
            methods[METHOD_js_getAppwidth7].setDisplayName ( "" );
            methods[METHOD_js_getDelta8] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("js_getDelta", new Class[] {})); // NOI18N
            methods[METHOD_js_getDelta8].setDisplayName ( "" );
            methods[METHOD_js_getLines9] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("js_getLines", new Class[] {})); // NOI18N
            methods[METHOD_js_getLines9].setDisplayName ( "" );
            methods[METHOD_js_getLocked10] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("js_getLocked", new Class[] {})); // NOI18N
            methods[METHOD_js_getLocked10].setDisplayName ( "" );
            methods[METHOD_js_setAppheight11] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("js_setAppheight", new Class[] {java.lang.Integer.class})); // NOI18N
            methods[METHOD_js_setAppheight11].setDisplayName ( "" );
            methods[METHOD_js_setAppwidth12] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("js_setAppwidth", new Class[] {java.lang.Integer.class})); // NOI18N
            methods[METHOD_js_setAppwidth12].setDisplayName ( "" );
            methods[METHOD_js_setDelta13] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("js_setDelta", new Class[] {java.lang.Integer.class})); // NOI18N
            methods[METHOD_js_setDelta13].setDisplayName ( "" );
            methods[METHOD_js_setLines14] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("js_setLines", new Class[] {java.lang.String.class})); // NOI18N
            methods[METHOD_js_setLines14].setDisplayName ( "" );
            methods[METHOD_js_setLocked15] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("js_setLocked", new Class[] {java.lang.Integer.class})); // NOI18N
            methods[METHOD_js_setLocked15].setDisplayName ( "" );
            methods[METHOD_mouseClicked16] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("mouseClicked", new Class[] {java.awt.event.MouseEvent.class})); // NOI18N
            methods[METHOD_mouseClicked16].setDisplayName ( "" );
            methods[METHOD_mouseDragged17] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("mouseDragged", new Class[] {java.awt.event.MouseEvent.class})); // NOI18N
            methods[METHOD_mouseDragged17].setDisplayName ( "" );
            methods[METHOD_mouseEntered18] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("mouseEntered", new Class[] {java.awt.event.MouseEvent.class})); // NOI18N
            methods[METHOD_mouseEntered18].setDisplayName ( "" );
            methods[METHOD_mouseExited19] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("mouseExited", new Class[] {java.awt.event.MouseEvent.class})); // NOI18N
            methods[METHOD_mouseExited19].setDisplayName ( "" );
            methods[METHOD_mouseMoved20] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("mouseMoved", new Class[] {java.awt.event.MouseEvent.class})); // NOI18N
            methods[METHOD_mouseMoved20].setDisplayName ( "" );
            methods[METHOD_mousePressed21] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("mousePressed", new Class[] {java.awt.event.MouseEvent.class})); // NOI18N
            methods[METHOD_mousePressed21].setDisplayName ( "" );
            methods[METHOD_mouseReleased22] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("mouseReleased", new Class[] {java.awt.event.MouseEvent.class})); // NOI18N
            methods[METHOD_mouseReleased22].setDisplayName ( "" );
            methods[METHOD_paint23] = new MethodDescriptor(org.coh.signature.Signature.class.getMethod("paint", new Class[] {java.awt.Graphics.class})); // NOI18N
            methods[METHOD_paint23].setDisplayName ( "" );
        }
        catch( Exception e) {}//GEN-HEADEREND:Methods

    // Here you can add code for customizing the methods array.
    
        return methods;     }//GEN-LAST:Methods

    private static java.awt.Image iconColor16 = null;//GEN-BEGIN:IconsDef
    private static java.awt.Image iconColor32 = null;
    private static java.awt.Image iconMono16 = null;
    private static java.awt.Image iconMono32 = null;//GEN-END:IconsDef
    private static String iconNameC16 = null;//GEN-BEGIN:Icons
    private static String iconNameC32 = null;
    private static String iconNameM16 = null;
    private static String iconNameM32 = null;//GEN-END:Icons

    private static final int defaultPropertyIndex = -1;//GEN-BEGIN:Idx
    private static final int defaultEventIndex = -1;//GEN-END:Idx

    
//GEN-FIRST:Superclass

    // Here you can add code for customizing the Superclass BeanInfo.

//GEN-LAST:Superclass
	
    /**
     * Gets the bean's BeanDescriptors.
     * 
     * @return BeanDescriptor describing the editable
     * properties of this bean.  May return null if the
     * information should be obtained by automatic analysis.
     */
    public BeanDescriptor getBeanDescriptor() {
	return getBdescriptor();
    }

    /**
     * Gets the bean's PropertyDescriptors.
     * 
     * @return An array of PropertyDescriptors describing the editable
     * properties supported by this bean.  May return null if the
     * information should be obtained by automatic analysis.
     * <p>
     * If a property is indexed, then its entry in the result array will
     * belong to the IndexedPropertyDescriptor subclass of PropertyDescriptor.
     * A client of getPropertyDescriptors can use "instanceof" to check
     * if a given PropertyDescriptor is an IndexedPropertyDescriptor.
     */
    public PropertyDescriptor[] getPropertyDescriptors() {
	return getPdescriptor();
    }

    /**
     * Gets the bean's EventSetDescriptors.
     * 
     * @return  An array of EventSetDescriptors describing the kinds of 
     * events fired by this bean.  May return null if the information
     * should be obtained by automatic analysis.
     */
    public EventSetDescriptor[] getEventSetDescriptors() {
	return getEdescriptor();
    }

    /**
     * Gets the bean's MethodDescriptors.
     * 
     * @return  An array of MethodDescriptors describing the methods 
     * implemented by this bean.  May return null if the information
     * should be obtained by automatic analysis.
     */
    public MethodDescriptor[] getMethodDescriptors() {
	return getMdescriptor();
    }

    /**
     * A bean may have a "default" property that is the property that will
     * mostly commonly be initially chosen for update by human's who are 
     * customizing the bean.
     * @return  Index of default property in the PropertyDescriptor array
     * 		returned by getPropertyDescriptors.
     * <P>	Returns -1 if there is no default property.
     */
    public int getDefaultPropertyIndex() {
        return defaultPropertyIndex;
    }

    /**
     * A bean may have a "default" event that is the event that will
     * mostly commonly be used by human's when using the bean. 
     * @return Index of default event in the EventSetDescriptor array
     *		returned by getEventSetDescriptors.
     * <P>	Returns -1 if there is no default event.
     */
    public int getDefaultEventIndex() {
        return defaultEventIndex;
    }

    /**
     * This method returns an image object that can be used to
     * represent the bean in toolboxes, toolbars, etc.   Icon images
     * will typically be GIFs, but may in future include other formats.
     * <p>
     * Beans aren't required to provide icons and may return null from
     * this method.
     * <p>
     * There are four possible flavors of icons (16x16 color,
     * 32x32 color, 16x16 mono, 32x32 mono).  If a bean choses to only
     * support a single icon we recommend supporting 16x16 color.
     * <p>
     * We recommend that icons have a "transparent" background
     * so they can be rendered onto an existing background.
     *
     * @param  iconKind  The kind of icon requested.  This should be
     *    one of the constant values ICON_COLOR_16x16, ICON_COLOR_32x32, 
     *    ICON_MONO_16x16, or ICON_MONO_32x32.
     * @return  An image object representing the requested icon.  May
     *    return null if no suitable icon is available.
     */
    public java.awt.Image getIcon(int iconKind) {
        switch ( iconKind ) {
        case ICON_COLOR_16x16:
            if ( iconNameC16 == null )
                return null;
            else {
                if( iconColor16 == null )
                    iconColor16 = loadImage( iconNameC16 );
                return iconColor16;
            }
        case ICON_COLOR_32x32:
            if ( iconNameC32 == null )
                return null;
            else {
                if( iconColor32 == null )
                    iconColor32 = loadImage( iconNameC32 );
                return iconColor32;
            }
        case ICON_MONO_16x16:
            if ( iconNameM16 == null )
                return null;
            else {
                if( iconMono16 == null )
                    iconMono16 = loadImage( iconNameM16 );
                return iconMono16;
            }
        case ICON_MONO_32x32:
            if ( iconNameM32 == null )
                return null;
            else {
                if( iconMono32 == null )
                    iconMono32 = loadImage( iconNameM32 );
                return iconMono32;
            }
	default: return null;
        }
    }

}

I should add, this works fine in NetBeans using a JFrame Form.

(!?!?)

you need to specify the package in manifest file, like : org/coh/signature/Signature.class , not only the file (Signature.class)

Hi Lvostinar,

Thanks much for the tip – now I can place it on the form and draw in the area nicely, which is fantastic! But I’ve run into another problem – when I try to print or show printpreview, I get the background text “Signature” and the box printing but the actual drawn signature doesn’t show up. It’s as if the printpreview and print create another instance of the bean without the data in the Vector lines, so all I get is the box and the word “Signature.”

I also get a strange artifact when in the print preview, when the bean is on the form, which looks like a continuous call to paint(). The size and location of the artifact depend on the location of the bean on the form.

I notice others seem to have posted similar issues with printpreview for other beans. Is there a workaround for this or was it ever fixed? I’m using 3.1 developer right now.

Best,

Jon

UPDATE: I just checked it in Servoy 4.0.5 and still see the artifact and no data.

printing generated images in beans is very hard in Servoy.
You can try to get a picture from the bean first and use that for print or print preview.

we us this also in combination with a barcode bean.

Thanks guys,

I created a function in the bean to return a JPEG, then write that into a media variable before printing. This is working well, thanks for the help!

Jon