Wednesday, July 15, 2009

Debugging Applets

In the Exceptions Trail of the Java Tutorial, the catch Blocks lesson gives the following as an example of a catch block:

} catch (IOException e) {
System.err.println("Caught IOException: "
+ e.getMessage());
}

This works fine if you are running an app from the command line, or even an applet using appletviewer, but it is absolutely useless if you are testing an applet in an ordinary browser.

My applet is supposed to record performance data, and I found it frustrating not knowing whether it had actually written anything to the database without running a separate query on the database. I therefore added a GUI object to the applet to display the message:

  if(dbDEBUG) {
jTADiagnosics = new JTextArea();
jTADiagnosics.setFont(new Font("Arial", Font.PLAIN, 14));
jTADiagnosics.setColumns(60);
jTADiagnosics.setRows(2);
c.insets = new Insets(0,10,10,10); //12oc,9oc,6oc,3oc padding
c.gridx = 0; //aligned with button 2
c.gridy = 8; //eighth row
c.gridwidth = 3; //3 columns wide
add(jTADiagnosics, c);
}

and a method to display errors in this text area:

   private void addItem(String newWord) {
if(dbDEBUG) {
System.out.println(newWord);
jTADiagnosics.append(newWord);
}
}

Then for the reasons explained in my previous blog, the arguments passed to this method are the return values of the method used to do the data related stuff - loading the driver, making the connection, and most importantly, adding lines to the database.

On reflection, I think I have written these two blogs back to front, and the last one should have come before this one, but who cares? My intention now is to leave coding for a while and get back to Rasch theory.

Thursday, July 9, 2009

Functions

When I was using Visual Basic I never really got to grips with functions. I knew how to use them, and liked them, if someone else wrote them. For example the function log(x) returns the logarithm of x, and is often handy to use. But I took the view that all the useful functions had already been written, and I could not see why I should ever need to write one myself.

On the other hand, I found simple subroutines very useful, especially for chunks of code which might be called in more than one circumstance. But I never made a conceptual link between a function and a subroutine.

In Java, what VB calls a function is called a method, and what VB calls a subroutine is called a void method, so one is led to think about the similarities between the two constructs.

My stereotype of a function is a lump of code with a single unambiguous purpose. For example the function log(x) would never be used for anything except to calculate the logarithm of a number. It was only when I started coding in java that it occurred to me that what is returned by a method might be like a bi-product of code, the principal purpose of which is to do something completely different.

For example in my Java Math Test, I have an applet which displays the user interface, and supporting classes which do the grunt work, including most recently the data connection. I had got beyond testing with the command line applet viewer, and wanted to try the applet in a regular browser calling files from a web server. As I could no longer use standard output for debugging messages, I wanted to display a message in a GUI object on the applet itself.

Most of the stuff done by my supporting classes is done by calling void methods. But in order to check whether or not a connection had been made, I dressed up the connection code in a method returning a string. The code looked as follows:

public String dataConn() {
try {
String strconn = "jdbc:derby://192.168.2.3:1527/dbAMJ";
liveconn = DriverManager.getConnection( strconn );
smt = liveconn.createStatement();
buffer = "connection succeeds ";
} catch(Exception ex) {
buffer = "connection fails ";
}
return buffer;
}

And it was called by the simple expression:

addItem(qTrack.dataConn());

Where addItem is a method on the main applet which adds short diagnostic messages to a string of messages and displays them in a text label. On the surface (at least from where it is called) it looks as if dataDriv is a method or function designed to do something with text, whereas in fact it's primary purpose is to make a data connection, and the text it returns is a bi-product for diagnostic purposes.

Sunday, July 5, 2009

Coding for Rasch

This is my first day back with my main project for two months. This is the page I wanted to write after my 24 April post. The question I want to address is what fields do I need to store data for subsequent Rasch analysis?

Rasch analysis investigates the interaction between test items and test participants. Core fields would therefore include the test item, the participant, and results of the interaction.

Recording the item is pretty easy. If a math student is asked for the product of two and two, the item is 2x2=?

Recording the student is a bit harder. It opens up a whole hornets nest of privacy and data protection issues. However, the analysis does not really require demographic details. All we need to record is that an entity addressing Item A of a session was the same entity addressing Item B in the same session. It does not matter that the same person may later complete another session. From a Rasch perspective, it is a new entity. It may be the same person a little older. It may be the same person with a headache, or feeling tired. It may even be the same person feeling the same; or it may be a different person with similar performance capabilities. All that matters is that data from a specific session is identified for the purpose of the analysis. For the time being I think a date stamp (in milliseconds) will suffice. If the tool ever became really popular, perhaps the date stamp could be augmented by an IP address.

For the interaction details, the Boolean result of the interaction is essential for conventional Rasch analysis, and for my preferred scoring rate metric, the time (in milliseconds) taken to achieve that result, is also essential. That can be converted into a scoring rate for the item, expressed as correct answers per minute (capm).

That will probably do for the main raw data table. That will be the data recorded in each session.

But what information should be served back to the participant? The most ordinary drill and practice program gives the user a raw score as they progress through an activity. Some (such as Mathletics) introduce the element of time, but usually following the model of a conventional speed test. From a psychometric perspective this is fraught with theoretical problems which have been amply discussed in the academic literature, although I don't have any references at my finger tips just now. Few, if any, give a scoring rate on individual items.

We can do that and go a stage further. Data drawn from the raw table can be processed to produce estimations of item difficulty. These estimations can be combined with real time interaction data to feed back estimations of student ability. This information can be displayed for students as they use the tool.

Saturday, July 4, 2009

Linguistic Rules

I have been silent for six weeks because I have been bogged in theory. At the end of my last blog I reported that I had been urged to revisit the core language lessons. So I went right back to the concepts trail and looked up the Inheritance lesson to better understand the extends key word, and the Interface lesson to better understand the implements key word. Then in the Language Basics trail the Variables lesson refreshed my memory on the static key word, Class Variables (Static Fields), Instance Variables (Non-Static Fields), and Local Variables. The this key word is described in the Classes and Objects trail in a lesson by the same name.

After re-reading this lessons I was able to better understand the posts in this thread at the end of which I posted some code, which for me tied it all together, and solved my event listener problem.

I went on to have problems with Window Listeners, but they arose because of my obsession with walking before I run. My main project is going to be web based, so I shall never need a window listener. I was fiddling around with a JFrame, because I had a mental blockage with applets, perhaps because building an applet represents the end game for me.

When I bit the bullet and embraced the Applet Trail I was reminded that the Applet interface has two built in "closing" events, Stop and Destroy. I therefore had no need for a window listener. However, there was another problem I had not bargained for: security restrictions of which the most serious for me was the inability to read or write files on the host.

When I first read this I gave it little attention because I don't want to write to the client, I want to store information at my end. But as I muddled my way through the mire of data connections, I learnt that the (easiest to use) embedded Derby database engine writes on the local host.

I therefore needed to take another bull by the horns and embrace the Apache Derby Documentation. This is well written, with easy to follow examples, but the was a lot to learn. Essentially I needed to run the NetServer application on my web server, specify that it should receive connections from anywhere, and then use the client driver with my applet.

There was no need for any other supporting classes. As long as the communication was with a server app running from the same address from with the applet was downloaded, all the code can be contained in the single applet. Put another way, calling supporting non-applet classes from the applet to make the data connection is not a way around the security restrictions. I had seen some sample code which used supporting classes to make a connection, and I foolishly thought I could use it to break the rules, but I could not.

Instead, I ended up making a successful test connection straight out of an applet, and I posted the code at the end of this thread for future reference.

Saturday, June 13, 2009

Action Listeners

In my last blog I recorded a dismal failure to hand-code a data connection from within NetBeans, but an eventually successful connection using a hand coded app run from the command line. I therefore resigned myself to learning Swing, so that I could rebuild my Java Math Test by hand.

The lessons in the Swing Trail are generally very well written, in sharp contrast to this in the JDBC Trail. Each lesson is illustrated with a mini app, and a link to the complete code is provided early in the lesson, along with a screen shot to the app running, and a JNLP link to run it from within the browser. If you choose to download the code, it compiles and runs without a glitch.

My only criticism, or suggestion for an improvement, would be the addition of a few "application" (in the literal sense of the word) lessons, which combine features from different sub-trails.

My own particular interest is in combining GridBag layout with Event or Action Listeners. You'd think it would be simple enough, but I am having great difficulty either adding event listening code to a test app using the GridBag layout, or converting a sample event listening app to the GridBag layout.

My first preference would be to add an Action Listener to to an app using the GridBag layout, because I have already built a front end using code from the component and layout lessons.

Many of the component lessons include some even handling code, but I refer to the Introduction to Event Listeners lesson, because it lays out the theory from first principles. Like other lessons in the Swing trail it provides the full code for an example, and it then goes on to say: "Here is the code that implements the event handling for the button:

public class Beeper ... implements ActionListener {
... //where initialization occurs:
button.addActionListener(this);
...
public void actionPerformed(ActionEvent e) {
...//Make a beep sound... } }

So it looks as if there are just three easy steps to adding event listener code to an existing class. First you add "implements ActionListener" to the class declaration, then you add the line "button.addActionListener(this);" somewhere in the code defining the button, and finally you write a method for the event: "public void actionPerformed(ActionEvent e) { ... }. That looks simple enough. I shall begin with a shortened version of the GridBag code, and add these lines one by one.

First I compile and run the existing code to check that it really works. It does. Then I add "implements ActionListener" to the class declaration. When I try to compile I get the error:

GBLD1.java:12: cannot find symbol
symbol: class ActionListener
public class GBLD1 implements ActionListener {

So I add:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

to the import list and try again. I now get the error message:

GBLD1.java:17: GBLD1 is not abstract and does not override abstract method  actionPerformed(java.awt.event.ActionEvent) in java.awt.event.ActionListener
public class GBLD1 implements ActionListener {

For completeness, I'll add the action listener to the button and try to compile again. Now there is a new error:

GBLD1.java:25: non-static variable this cannot be referenced from a static context
button.addActionListener(this);

This error message opened a whole can of worms, and prompted me to post a question in the swing forum.

To cut a long story short the answer was to replace the word "this" with an instance of the class as follows:

button.addActionListener(new GBLD2());

where GBLD2 was the classname of my test app. This enabled me to insert an action listener into my Gridbag test app, such that the main button gives a beeping sound when clicked. The method to produce the beep was:

public void actionPerformed(ActionEvent e) {
Toolkit.getDefaultToolkit().beep();
}

So far this is all I have managed by way of action code. Any attempt to reference objects on the form generates errors. According to the thread, I need to refer back to the lessons on "static, instance, and reference".