Category Archives: Howto

Optional Parameters another way.

I’ve always liked the way that in C++ and other languages you can have optional parameters and I’ve been messing around with ways to do it in JAVA, so I came up with a class that extends the HashMap and makes it quite a neat way of having optional parameters in code.

Here’s the class

package utilclasses;
import java.util.HashMap;
/**
 *
 * Another fine Java Class http://www.netbeansboy.org
 *
 * @author paulc
 */
public final class optional extends HashMap {
 
 optional(Object... objects) {
 put(objects);
 }
 
 public void put(Object... objects) {
 for (int i=0;i<objects.length;i=i+2) {
 Object key=objects[i];
 Object value=objects[i+1];
 put(key,value);
 }
 }
 
 
 
}

 

As you can see it has one routine called put that is called in the constructor that constructs the hash map, so it’s use in your code is pretty simple.

 
 opt(new optional("Name","John","Age",34,"Address","test"));
 
 
 
 }
 
 
 
 private static void opt(optional y) {
 System.out.println(y.get("Name"));
 System.out.println(y.get("Age"));
 System.out.println(y.get("Address"));
 System.out.println(y.get("22"));
 
 }

Which produces the result:-

John
34
test
null

Note that the last result is null because optional parameter 22 has not been set.  Note however this will only work with Java 8. I’ve actually used their optional solution to create mine! Only that I really like the idea of just filling out key values so you can see in your code the variables.

Creating an automatic backup script for mysql

Ok this is really step by step. There’s nothing complicated

1. Created a backup folder as ROOT

> sudo su
enter password
> cd /
> mkdir backup
> cd backup

now create a shell script I use NANO to do this. (don’t forget to change the username and password to match yours)

> nano backup.sh

cd /backup
mysqldump -u username -ppassword --all-databases>backup`date +%a`.sql

Save the file. backup.sh

Now edit the cron table

> crontab -e
01 02 * * *  /backup/backup.sh

and save.

This will cause your backup to happen every morning at 2am.

It’s a good idea to test your backup routine sh backup.sh before leaving it to cron to do the work.

 

Finding out where I am without an external API.

My work is incredibly interesting. I do a LOT of mapping and location software, often it’s easy to plug in to something like Google Maps who provide their awesome API for programmers to hack. But sometimes this isn’t possible.

Of of my projects involves a world map with a plot of different devices locations. However in this case, as it was run in a back end query it would not be covered by any web api’s license. My own solution was needed. The first thing I did was to get some data, a cities table with 2.6 million entries is available free on the internet, and a countries table, I modified the cities table to include the country name.

Then I simply used a nested query on the cities table.

select * from cities where (lat>4.3142004 and lat<4.7142) 
and (cities.long>-74.0833 and cities.long<-73.683304) limit 1

This effectively is a box surrounding the point I’m looking for. Note that if the box fails to find anything I can just increase the parameters and rerun the query.

You can see that the figures form a box around the point I’m looking for, in this case I did not need the address, just what country it was in. (returned the whole record for testing).

Incidentally the cities table is pretty interesting, you wouldn’t believe how many London’s there are!

The cities file can be downloaded here

Primefaces Tree in a layout or panel doesn’t work

I must be losing more hair than anything. The tree function in a layout doesn’t work, although the backing bean is called the selectedItems array passed to it is empty. So here’s the fix.

Your code now looks like this probably (or something like it).

<p:panel style="height:80%">   <p:tree selection="#{indextree.selectedNodes}"
 update="Map" propagateSelectionUp="true" propagateSelectionDown="true"
 nodeSelectListener="#{indextree.onNodeSelect}" id="tree"
 style="font-size:12pt" selectionMode="checkbox" value="#{indextree.root}" var="node"> <p:treeNode> <h:outputText value="#{node}"/> </p:treeNode>
</p:tree>
</p:panel>

So simply create another xhtml file and put the tree in it on it’s own. In this case I called it treeTest.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:p="http://primefaces.prime.com.tr/ui" xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core">
<f:view contentType="text/html"><h:head>
<title>Tracking</title>
</h:head>
<h:body style="font-size:8pt" >
<h:form id="boris" enctype="multipart/form-data">
<p:tree selection="#{indextree.selectedNodes}" update="Map" propagateSelectionUp="true" propagateSelectionDown="true" nodeSelectListener="#{indextree.onNodeSelect}" id="tree" style="font-size:12pt" selectionMode="checkbox" value="#{indextree.root}" var="node">
<p:treeNode>
<h:outputText value="#{node}"/>
</p:treeNode>
</p:tree></h:form></h:body>
</f:view>
 </html>

Now in your original file replace your tree code with an iframe! Tada, it all works! (note it should have < at the start and > at the end but wordpress goes a bit mad if I do that.

iframe src="treeTest.xhtml" style="height:80%;border-style:none;border-width:1px;" ></iframe

By the way this is fixed in the latest V3.0M

Installing Glassfish 3.1 ubuntu

Install Java first!

sudo su  
apt-get install unzip
wget http://dlc.sun.csom.edgesuite.net/glassfish/3.1/release/glassfish-3.1.zip
sudo unzip glassfish-3.1.zip
mv glassfish3 /opt
useradd --system glassfish -d /opt/glassfishv3
chgrp -R admin /opt/glassfishv3
cd /opt/glassfish3
chmod -R +x bin/
cd bin
./asadmin start-domain domain1
cd /etc/init.d
nano glassfish

(or you can use your favourite editor!)

GLASSFISHPATH=/opt/glassfish3/bin
echo "starting glassfish from $GLASSFISHPATH"
cd /opt/glassfish3/bin
./asadmin start-domain domain1

(PRESS CTRL X) Y (save)

sudo update-rc.d glassfish defaults
chmod +x glassfish

And reboot to check it comes up.

http://youripaddress:4848/

Gotchas!

OpenJDK doesn’t seem to work you need to use the Java SDK

If you install java you may find that there is no link to it, change to the bin folder.

cd /bin

and create a link

ln -s /usr/lib/jvm/java-6-sun/jre/bin/java java

Netbeans Problem “Enable-secure-admin”

Gotcha 2 is when trying to connect Netbeans to the server and you get some message about Enable-secure-admin here’s how to fix it

run asadmin on the glass fish server in terminal execute the following:

a) enable-secure-admin
b) stop-domain domain1
c) start-domain domain1
d) list-domains

See: http://download.oracle.com/docs/cd/E18930_01/html/821-2435/gkofl.html

accept the certificate. If you type in ‘y’

 

 

EJB downloading an excel file from JSP

The Calling Page

Let’s say you have a button on a JSP page that calls it. One of the problems is stopping the page opening as blank. So here’s the calling button

<form method="post" action="#">
 <input type="button" value="Download" onClick="return downloadButton();"/>
        </form>
        

The iFRame is used to trigger the excel call, and here’s the download button javascript.

function downloadButton() {
 
    document.getElementById("excel").src="exportxl.jsp?sql=select * from mytable";
    return false;
    
}

The Responding Page

Now the Calling JSP Page that goes off and gets the Excel Spreadsheet from the EJB, I have an EJB called server and the corresponding remote interface “server remote” note that these must be registered in the xml files in the web app so the web app can see the remote interface in the EJB

<%-- 
    Document   : exportxl
    Created on : Aug 1, 2011, 8:36:23 AM
    Author     : paulc
--%>
<%@ page import = "java.sql.*" %>
<%@ page import = "javax.naming.Context" %>
<%@ page import = "javax.naming.InitialContext; "%>
<%@ page import = "PHJ.*" %>
<%@page contentType="application/vnd.ms-excel" pageEncoding="UTF-8"%>
<%

    PHJ.ServerRemote jobManagerBean = null;
    try {
        Context c = new InitialContext();
        jobManagerBean = (PHJ.ServerRemote) c.lookup("java:comp/env/Server");
    } catch (Exception ne) {
        System.out.println("Could not find Job Manager Bean " + ne);
        out.println("Could not find Job Manager Bean");
        return;
    }

    response.setHeader("Content-disposition", "attachment; filename=excelexport.csv");

    String sql = "";
    if (request.getParameter("sql") != null) {
        sql = request.getParameter("sql");

        out.print(jobManagerBean.prepareCSVForExcel(sql));

    } else {
        out.println("Error, No SQL statement specified");

    }
    
    

%>

The EJB

And here’s the routine in the EJB.

 
    private Connection conn;
    private String dbName = "myJNDIRESOURCE"; // make sure you have JNDI resource setup 
    /* This routine gets a connection from the above DBName, however, if it can't find it it lists the available JNDI resourcees
     * to the console or log
     */ 
    private Connection getConnection() {
        if (conn != null) {
            try {
                if (!conn.isClosed()) {
                    return conn;
                }
            } catch (SQLException ex) {
                // Do nothing just carry on.
            }

        }
        InitialContext ic = null;

        Query q = null;

        try {
            // initialize JNDI lookup parameters
            ic = new InitialContext();
            DataSource ds = (DataSource) ic.lookup(dbName);
            conn = ds.getConnection();
        } catch (Exception e) {
            try {
                System.out.println("JNDI Resource " + dbName + " not found " + e);
                NamingEnumeration children = ic.list("");
                while (children.hasMore()) {
                    NameClassPair ncPair = (NameClassPair) children.next();
                    System.out.print(ncPair.getName() + " (type " + ncPair.getClassName() + ")");

                }
                System.out.println("**** CANNOT FIND DATABASE ************************");
                children = ic.list("jdbc");
                while (children.hasMore()) {
                    NameClassPair ncPair = (NameClassPair) children.next();
                    System.out.print(ncPair.getName() + " (type " + ncPair.getClassName() + ")");

                }
                System.out.println("****************************************");
            } catch (Exception f) {
                System.out.println("Error 57:" + f);
            }
            System.out.println("ERROR 52: " + e);
            return null;
        }
        return conn;

    }

    public String prepareCSVForExcel(String sSQL) {

        String sResult = "";
        try {
            conn = getConnection();
            Statement s = conn.createStatement();
            ResultSet r = s.executeQuery(sSQL);
            // feldnames
            for (int i = 1; i != r.getMetaData().getColumnCount(); ++i) {
                sResult = sResult + r.getMetaData().getColumnName(i) + ",";


            }
            sResult = sResult + "\n";

            while (r.next()) {
                for (int i = 1; i != r.getMetaData().getColumnCount(); ++i) {
                    try {
                    if (r.getObject(i) != null) {
                        sResult = sResult + r.getString(i) + ",";
                    } else {
                        sResult = sResult + ",";

                    }
                    } catch (Exception e) {
                        sResult = sResult + ","; // Happens when there is a conversion error to a tiemstamp
                    }


                }
                sResult=sResult+"\n";



            }




        } catch (Exception e) {
            return e + "";
        }
        return sResult;
    }

Java/JSP Global Variables

JSP

To set

application.setAttribute("key","hello");

To get

application.getAttribute("key").toString();

Java (you could do this in JSP actually)

Create a class with static variables.

public class GVariables() {
   public static String key="hello";

}

To use;

String sMode=new GVariables().key;

Open Meetings! Well worth a look…

This is nothing to do with Netbeans (sorry folks!) but for some time our development department have been using an IRC chat client, limited but worked. We just got a whizzy new second hand server and I decided to explore what we could do with some more advanced conferencing.

I came accross this…

http://code.google.com/p/openmeetings/wiki/InstallationOpenMeetings

This is an awesome bit of software and for our department I had it set up in 15/20 minutes! (not including downloads) but you must follow the instructions down to the letter, down load your package from the INSTALLATION page.

Good job guys!

Woodstock and AJAX with DHTMLXGRID (Netbeans 6.5)

Did you know that you can use the great woodstock components with DHTMLXGRID (and all the other components), this is the first of a series of articles to show you how. (http://www.dhtmlx.com/)

Before you start – if you are coding Javascript like this you best switch to Firefox and install the FIREBUG plugin, this lets you see whats going on with javascript pages like you’ve never done before. It will also help you identify the id’s of components before you use them and see if you get any problems.

The first thing to do is to copy the DHTMLXGRID javascript and CSS code into your Resources directory of your web project. Copy the whole of the codebase directory including the subdirectories, just drag and drop them.

Now create a new page and add a layout panel called it grdJOBDISPLAY Stretch it out to the size you want.

One of the problems we have is that we want to do some javascript that runs after the component tree is loaded, this happens after the page is loaded, I found that doing onload didn’t work, so you have to create a Static Text box, turn of ESCAPE and then in the text box put

<script language=”javascript”>
initgrid();

</script>

Now switch to your JSP it’s time to implement the javascript for the grid.

First, between the <head> tags we’ll add the code to load the grid support

<webuijsf:link id=”link91″ url=”/resources/dhtmlxgrid.css”/>
<webuijsf:script id=”link29″ url=”/resources/dhtmlxcommon.js”/>
<webuijsf:script id=”link39″ url=”/resources/dhtmlxgrid.js”/>
<webuijsf:script id=”link49″ url=”/resources/dhtmlxgridcell.js”/>
<webuijsf:script id=”link59″ url=”/resources/ext/dhtmlxgrid_srnd.js”/>
<webuijsf:script id=”link69″ url=”/resources/ext/dhtmlxgrid_filter.js”/>
<webuijsf:script id=”link71″ url=”/resources/ext/dhtmlxgrid_splt.js”/>
<webuijsf:script id=”link331″ url=”/resources/ext/dhtmlxgrid_hmenu.js”/>

And finally a section of script that will run to initialise the grid. In this case you can see my code for a real screen this is more complex that you will use, here I’m using the dynamic loading grid but you can adjust the code for your own use. Note that if you are going to use the dynamic loading grid with a SQL server you should be using some paging code to return the pages of data that is required, this is easy with SQL 2005 and MYSQL (LIMIT) but with SQL 2000 it is a complete dog.

To do paging with SQL Server 2000 I use http://esersahin.wordpress.com/2008/11/24/efficient-and-dynamic-server-side-paging-with-sql-server-2000/ this works like a dream and more than makes up for the lack of it working otherwise.

Also in this code I stretch the grid to be the width of the screen.

                        getElementByIdCompatible('form1:grdJOBDISPLAY').style.height=(pageHeight()-200)+"px";
                        getElementByIdCompatible('form1:grdJOBDISPLAY').style.width=(pageWidth()-30)+"px";

And in fact I make it the height of the screen – 200 pixels.

Note that here I also have a couple of other hidden fields (HIDDEN boxes) I use to pass data from the javascript at the front to the code at the back end.

form1:layoutPanel1:txtTABLENAME – stores the tablename to pull from, I dynamically set this when searching etc. It is bound to a variable stored in the session bean so I can set it or read it from the backing bean OR javascript.

form1:layoutPanel1:txtSQL- stores the WHERE statement that I’m going to use to filter the data in the grid. Again, bound to a session bean variable means that I can have a button you click on that changes the where statement.

<webuijsf:markup id="gridscript">
                        <script language="javascript">

                        var gridQString = "";

                        // called from a javascript function

                        function init() {
                        getElementByIdCompatible('form1:grdJOBDISPLAY').style.height=(pageHeight()-200)+"px";
                        getElementByIdCompatible('form1:grdJOBDISPLAY').style.width=(pageWidth()-30)+"px";
                        mygrid = new dhtmlXGridObject('form1:grdJOBDISPLAY');
                        mygrid.imgURL = "img/";
                        mygrid.setHeader("Job No, Job Date,POD,Hist, Svc,Sub,Haz,Pcs,Wgt,Acc No,Customer,Co Name, Town, Driver, Hdlg Dep,Close Time,Status,Print ");
                        mygrid.setInitWidths("100,100,60,60,50,50,50,50,50,100,200,200,200,100,200,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100");
                        mygrid.setColAlign("left,left,center,left,left,left,left,left,left,left,left,left,left")
                  //      mygrid.setColTypes("ro,ro,ro,ro,ro,ro,ro,ro,ro,ro,ro,ro,ro,ro,ro");
                        mygrid.setColSorting("str,date,str,str,str,str,str,str,str,str,str,str,str,str")
                        mygrid.setSkin("light");
                        mygrid.setDateFormat("%d/%b/%Y");
                        mygrid.enableHeaderMenu();
                        mygrid.setAwaitedRowHeight(25);

                        // mygrid.attachHeader("#text_filter,#combo_filter,#numeric_filter");

                        // NOTE YOU NEED TO INSTALL A STORED PROCEDURE IN THE SQL SERVER TO MAKE THIS WORK

                                        mygrid.attachHeader("#text_filter,#rspan,#rspan,#rspan,#rspan,#rspan,#rspan,#rspan,#rspan,#text_filter,#rspan,#rspan,#rspan,#text_filter,#text_filter,#rspan,#text_filter");
                        mygrid.init();
                        // mygrid.splitAt(1);
                        gridQString ="../jobscreendriver.jsp?tbl="+getElementByIdCompatible("form1:layoutPanel1:txtTABLENAME").value+"&amp;whr="+getElementByIdCompatible("form1:layoutPanel1:txtSQL").value;
                        mygrid.loadXML(gridQString);
                        mygrid.enableSmartRendering(true);

                        var sLastSQLWhere='';

                        mygrid.attachEvent("onFilterStart",function(cols,vals) {

                        var sAND='';
                        var sSQLWhere='';
                        if (vals[0]!='') {
                            sSQLWhere="jobno LIKE 'PERCENT"+vals[0]+"PERCENT'"
                            sAND=" AND "
                        }
                        if (vals[1]!='') {
                            sSQLWhere=sSQLWhere + sAND+" accountno LIKE 'PERCENT"+vals[1]+"PERCENT'";
                            sAND=" AND ";
                        }
                        if (vals[2]!='') {
                            sSQLWhere=sSQLWhere + sAND+" isporfleetid LIKE 'PERCENT"+vals[2]+"PERCENT'";
                            sAND=" AND ";
                        }
                         if (vals[3]!='') {
                            sSQLWhere=sSQLWhere + sAND+" handlingdepot LIKE 'PERCENT"+vals[3]+"PERCENT'";
                            sAND=" AND ";
                        }
                        if (sLastSQLWhere!=sSQLWhere) {
                        sLastSQLWhere=sSQLWhere;
                        mygrid.clearAll();
                        getElementByIdCompatible("form1:layoutPanel1:txtSQL").value=sSQLWhere;
                        mygrid.loadXML("../jobscreendriver.jsp?tbl="+getElementByIdCompatible("form1:layoutPanel1:txtTABLENAME").value+"&amp;whr="+ sSQLWhere);
                        mygrid.enableSmartRendering(true);
                        }
                        return false;  //block default filters
                        });

                        }

                        function getElementByIdCompatible(the_id) {
                        if (typeof the_id != 'string') {
                        return the_id;
                        }

                        if (typeof document.getElementById != 'undefined') {
                        return document.getElementById(the_id);
                        } else if (typeof document.all != 'undefined') {
                        return document.all[the_id];
                        } else if (typeof document.layers != 'undefined') {
                        return document.layers[the_id];
                        } else {
                        return null;
                        }
                        }

                        // Process the clicked Job button
                        function editJob(sJobNo) {
                        getElementByIdCompatible("form1:layoutPanel1:txtJOBNO").value=sJobNo.id;
                        getElementByIdCompatible("form1:layoutPanel1:cmdEDITJOB").click();
                        return false;
                        }

                        </script>
                    </webuijsf:markup>

Now then. You will need a JSP file to deliver the data to the grid –

            mygrid.loadXML("../jobscreendriver.jsp?tbl="+getElementByIdCompatible("form1:layoutPanel1:txtTABLENAME").value+"&amp;whr="+ sSQLWhere);

Here I have a JSP file that creates some xml – this is more complex than you might need for your applications but it does some interesting things with being able to filter data. You will have to adjust this to your database and situation, note that it uses the paging stored procedure to provide the data back to the grid on an SQL 2000 server.  Also I change the colour of the row to reflect the status of the record.

Lastly before I send the sql statement I replace the % signs with PERCENT and then convert it back in the code – you also need to filter out & signs in the xml and replace with &amp; otherwise you’ll get the “invalid XML statement”

<?xml version="1.0" encoding="ISO-8859-1"?>
<%@ page contentType="text/xml;charset=ISO-8859-1" %>
<%@ page import = "java.sql.*" %>
<%
        String db_ipp_addr = "insert ip address";
        String db_username = "insert username";
        String db_password = "insert password";
        String db_name = "insert database";

// set content type and xml tag

//   out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
// response.setContentType("text/xml");
// define variables from incoming values
        Integer posStart = 0;
        if (request.getParameter("posStart") != null) {
            posStart = new Integer(request.getParameter("posStart"));
        } else {
            posStart = 0;
        }

        Integer count = 0;
        if (request.getParameter("count") != null) {
            count = new Integer(request.getParameter("count"));
        } else {
            count = 20;
        }
        if (posStart.equals("0")) {
            posStart = 0;
        }

// connect to database
        Connection connection = null;
        Statement statement = null;
        Statement history = null;
        ResultSet rs = null;
        ResultSet Historyrs = null;

        String connectionURL = "jdbc:sqlserver://" + db_ipp_addr + ":1433;databaseName=" + db_name;

        Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
        connection = DriverManager.getConnection(connectionURL, db_username, db_password);
// connection.setCatalog("dbo");
// query to products table
        String sTableName = "dbo.tbljobs";
        if (request.getParameter("tbl") != null) {
            sTableName = request.getParameter("tbl");

        }

        String sql = "SELECT * FROM " + sTableName;
        String sCancelled = " Cancelled=0 AND ";

        if (request.getParameter("whr") != null) {
            if (request.getParameter("whr").toLowerCase().contains(" cancelled")) {
                sCancelled = "";
            }
            sql = sql.trim() + " WHERE " + sCancelled + " JobNo Not Like 'CR%' AND " + request.getParameter("whr");
        } else {
            sql = sql.trim() + " WHERE " + sCancelled + " JobNo Not Like 'CR%'";
        }
        sql=sql.trim();
        if (sql.substring(sql.length()-3,sql.length()).equals("AND")) {
            sql=sql.substring(0,sql.length()-3);
            }
        sql=sql.replace("PERCENT","%");
// if this is the first query - get total number of records in the query result
        String totalCount = "";
        if (posStart == 0) {
            String sqlCount = "Select count(*) as cnt from (" + sql + ") as tbl";
            statement = connection.createStatement();

            rs = statement.executeQuery(sqlCount);
            rs.next();
            totalCount = rs.getString("cnt");

            rs.close();
        } else {
            totalCount = "";
        }

        CallableStatement getData = connection.prepareCall("{call returnpage(?,?,?,?)}");
        getData.setString(1, sql);

        getData.setInt(3, posStart);
        getData.setInt(4, (posStart + count));
        try {
        getData.executeQuery();

        rs = getData.getResultSet();
        } catch (Exception e) {
            System.out.println (sql);
        System.out.println ("Error Getting Record "+e);
          }
// output data in XML format
        out.println("<rows total_count='" + totalCount + "' pos='" + posStart + "'>");
        String sThisColor;
        String sStatus;

        while (rs.next()) {

            sStatus = rs.getString("status").trim();

            sThisColor = "#ffffff";
            if (sStatus.equals("XXXX")) {
                sThisColor = "#ff0000";
            } else if (sStatus.equals("YYYYY")) {
                sThisColor = "#ffcc00";
            } else if (sStatus.equals("EEEEE")) {
                sThisColor = "#ffcc00";
            } 

            out.println("<row style=' border-width: 1px; border-style: solid; border-color: rgb(253, 253, 253) rgb(147, 175, 186) rgb(147, 175, 186) white;padding:1px;height:22px;background-color:" + sThisColor + "' id='" + rs.getString("jobno") + "'>");

            out.println("<cell>");
            out.println(rs.getString("field1"));
            out.println("</cell>");
            out.println("<cell>");
            out.println(rs.getDate("field2"));
            out.println("</cell>");
            out.println("<cell>");
            out.println(rs.getString("field4") + "");  // value for product name
            out.println("</cell>");
            out.println("</row>");
        }
        out.write("</rows>");

        rs.close();

%>

Have fun!

Autocomplete with Netbeans 6.1!

Ok – for those of you who are stuck like us with Netbeans 6.1 until Jasper Reports catches up with 6.5 this is how to do an autocomplete field with woodstock.

I hate to say this but once I’d worked it out it was pretty easy.

1. Download the latest WOODSTOCK nbm (netbeans plugin file) and install.
2. In your Session bean you need to create a routine to return the data, it must look like this

Public Option[] getDropDownOptions(String sFilter) {

// Put your code in here to create an array of options
// new Option(Key, Display text)
}
2. In your Visual Web project create a text box and turn on the AutoComplete property
3. In the AutoCompleteExpression field bind it to:-
#{SessionBean1.getDropDownOptions}

Thats it now you will get an autocomplete text field.

Don’t bother doing all the stuff in other blogs, you just don’t need it once you’ve updated to the next version of Woodstock.

Incidentally we have had to shelve Icefaces until at least after Christmas and I am looking at Infragistics because they have a VERY interesting Grid control that can dynamically load Grid data, useful when customers want to see a lot of data at once.