A demo applet. Copy into a file named AppletDemo.java.
/*
 * @file
 * A java demo applet of the data features of the Flash ClosedQuestion type.
 */
package nl.wur.closedquestionappletdemo;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.SwingUtilities;

/**
 * A demo applet for some of the features of the ClosedQuestion Java question.
 *
 */
public class AppletDemo extends javax.swing.JApplet {

	/**
	 * Get and set helpers for the various data types.
	 * This could all be done with only one, but for clarity we use 4.
	 */
	/**
	 * PostHelper for getting student data.
	 */
	private PostHelper infoGetHelper;
	/**
	 * PostHelper for getting question data.
	 * This is data that is not the students answer, but is student-specific,
	 * like a value of a random number generator.
	 */
	private PostHelper dataGetHelper;
	/**
	 * PostHelper for getting the students answer.
	 */
	private PostHelper answerGetHelper;
	/**
	 * PostHelper for setting the answer and data.
	 */
	private PostHelper dataAnswerSetHelper;

	/** Initializes the applet AppletDemo */
	@Override
	public void init() {
		try {
			java.awt.EventQueue.invokeAndWait(new Runnable() {

				public void run() {
					initComponents();
				}
			});
		} catch (Exception ex) {
			Logger.getLogger(this.getClass().getName()).log(Level.WARNING, null, ex);
		}
	}

	/**
	 * Method that starts the info-fetch action.
	 */
	private void startGetInfo() {
		jButtonGetInfo.setEnabled(false);
		jButtonCallQuery.setEnabled(false);
		if (infoGetHelper == null) {
			infoGetHelper = new PostHelper(getDocumentBase());
			infoGetHelper.addPostListener(new PostHelper.PostListener() {

				public void postDone() {
					doneGetInfo();
				}
			});
		}
		infoGetHelper.clearVars();
		infoGetHelper.addVar("action", "getInfo");
		infoGetHelper.addVar("format", "json");
		infoGetHelper.doPost();
	}

	/**
	 * Method that starts the call-query action. We use the same PostHelper
	 * as for the fetch-info action.
	 */
	private void startCallQuery() {
		jButtonGetInfo.setEnabled(false);
		jButtonCallQuery.setEnabled(false);
		int query = Integer.parseInt(jSpinnerQuery.getValue().toString());
		if (infoGetHelper == null) {
			infoGetHelper = new PostHelper(getDocumentBase());
			infoGetHelper.addPostListener(new PostHelper.PostListener() {

				public void postDone() {
					doneGetInfo();
				}
			});
		}
		infoGetHelper.clearVars();
		infoGetHelper.addVar("action", "query");
		infoGetHelper.addVar("query", "" + query);
		infoGetHelper.addVar("format", "json");
		infoGetHelper.doPost();
	}

	/**
	 * Callback method, used when the student info is done loading.
	 *
	 * This is called by the worker thread when it is finished. Therefore we
	 * must use SwingUtilities.invokeLater to update the GUI.
	 */
	private void doneGetInfo() {
		SwingUtilities.invokeLater(new Runnable() {

			public void run() {
				jTextPaneResponse.setText(infoGetHelper.getResponseData());
				jButtonGetInfo.setEnabled(true);
				jButtonCallQuery.setEnabled(true);
			}
		});

	}

	/**
	 * Method that starts the data-fetch action.
	 */
	private void startGetData() {
		jTextPaneResponse.setText("Fetching... Data...");
		jButtonGetData.setEnabled(false);
		if (dataGetHelper == null) {
			dataGetHelper = new PostHelper(getDocumentBase());
			dataGetHelper.addPostListener(new PostHelper.PostListener() {

				public void postDone() {
					doneGetData();
				}
			});
		}
		dataGetHelper.clearVars();
		dataGetHelper.addVar("action", "getData");
		dataGetHelper.doPost();
	}

	/**
	 * Callback method, used when the data field is done loading.
	 *
	 * This is called by the worker thread when it is finished. Therefore we
	 * must use SwingUtilities.invokeLater to update the GUI.
	 */
	private void doneGetData() {
		SwingUtilities.invokeLater(new Runnable() {

			public void run() {

				jTextAreaData.setText(dataGetHelper.getResponseData());
				startGetAnswer();
			}
		});
	}

	/**
	 * Method that starts the answer-fetch action.
	 */
	private void startGetAnswer() {
		jTextPaneResponse.setText("Fetching... Data... Answer...");
		if (answerGetHelper == null) {
			answerGetHelper = new PostHelper(getDocumentBase());
			answerGetHelper.addPostListener(new PostHelper.PostListener() {

				public void postDone() {
					doneGetAnswer();
				}
			});
		}
		answerGetHelper.clearVars();
		answerGetHelper.addVar("action", "getAnswer");
		answerGetHelper.doPost();
	}

	/**
	 * Callback method, used when the student answer is done loading.
	 *
	 * This is called by the worker thread when it is finished. Therefore we
	 * must use SwingUtilities.invokeLater to update the GUI.
	 */
	private void doneGetAnswer() {
		SwingUtilities.invokeLater(new Runnable() {

			public void run() {

				jTextAreaAnswer.setText(answerGetHelper.getResponseData());
				jButtonGetData.setEnabled(true);
				jTextPaneResponse.setText("Fetching... Data... Answer... Done.");
			}
		});
	}

	/**
	 * Method that starts the answer and data store action.
	 */
	private void startSetDataAnswer() {
		jTextPaneResponse.setText("Storing...");
		if (dataAnswerSetHelper == null) {
			dataAnswerSetHelper = new PostHelper(getDocumentBase());
			dataAnswerSetHelper.addPostListener(new PostHelper.PostListener() {

				public void postDone() {
					doneSetDataAnswer();
				}
			});
		}
		dataAnswerSetHelper.clearVars();
		dataAnswerSetHelper.addVar("action", "store");
		dataAnswerSetHelper.addVar("answer", jTextAreaAnswer.getText());
		dataAnswerSetHelper.addVar("data", jTextAreaData.getText());
		dataAnswerSetHelper.addVar("format", "json");
		dataAnswerSetHelper.doPost();
	}

	/**
	 * Callback method, used when the student answer and data is done saving.
	 *
	 * This is called by the worker thread when it is finished. Therefore we
	 * must use SwingUtilities.invokeLater to update the GUI.
	 */
	private void doneSetDataAnswer() {
		SwingUtilities.invokeLater(new Runnable() {

			public void run() {

				jTextPaneResponse.setText(dataAnswerSetHelper.getResponseData());
				jButtonSetData.setEnabled(true);
			}
		});
	}

	/** This method is called from within the init() method to
	 * initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is
	 * always regenerated by the Form Editor.
	 */
	@SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        jPanel1 = new javax.swing.JPanel();
        jButtonGetInfo = new javax.swing.JButton();
        jButtonGetData = new javax.swing.JButton();
        jButtonSetData = new javax.swing.JButton();
        jPanel3 = new javax.swing.JPanel();
        jButtonCallQuery = new javax.swing.JButton();
        jSpinnerQuery = new javax.swing.JSpinner();
        jPanel2 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTextPaneResponse = new javax.swing.JTextPane();
        jScrollPane2 = new javax.swing.JScrollPane();
        jTextAreaAnswer = new javax.swing.JTextArea();
        jScrollPane3 = new javax.swing.JScrollPane();
        jTextAreaData = new javax.swing.JTextArea();

        getContentPane().setLayout(new java.awt.GridBagLayout());

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Actions"));
        jPanel1.setLayout(new java.awt.GridBagLayout());

        jButtonGetInfo.setText("Fetch User Data");
        jButtonGetInfo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonGetInfoActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.PAGE_START;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        jPanel1.add(jButtonGetInfo, gridBagConstraints);

        jButtonGetData.setText("Fetch Answer & Data");
        jButtonGetData.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonGetDataActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        jPanel1.add(jButtonGetData, gridBagConstraints);

        jButtonSetData.setText("Store Answer & Data");
        jButtonSetData.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonSetDataActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        jPanel1.add(jButtonSetData, gridBagConstraints);

        jPanel3.setLayout(new java.awt.GridBagLayout());

        jButtonCallQuery.setText("Call Query:");
        jButtonCallQuery.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonCallQueryActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        jPanel3.add(jButtonCallQuery, gridBagConstraints);

        jSpinnerQuery.setModel(new javax.swing.SpinnerNumberModel(0, 0, 9, 1));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        jPanel3.add(jSpinnerQuery, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        jPanel1.add(jPanel3, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 0.1;
        getContentPane().add(jPanel1, gridBagConstraints);

        jPanel2.setLayout(new java.awt.GridBagLayout());

        jScrollPane1.setBorder(javax.swing.BorderFactory.createTitledBorder("Response"));
        jScrollPane1.setViewportView(jTextPaneResponse);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
        gridBagConstraints.weightx = 0.1;
        gridBagConstraints.weighty = 0.1;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        jPanel2.add(jScrollPane1, gridBagConstraints);

        jScrollPane2.setBorder(javax.swing.BorderFactory.createTitledBorder("Answer"));

        jTextAreaAnswer.setColumns(20);
        jTextAreaAnswer.setRows(5);
        jScrollPane2.setViewportView(jTextAreaAnswer);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 0.1;
        gridBagConstraints.weighty = 0.1;
        jPanel2.add(jScrollPane2, gridBagConstraints);

        jScrollPane3.setBorder(javax.swing.BorderFactory.createTitledBorder("Data"));

        jTextAreaData.setColumns(20);
        jTextAreaData.setRows(5);
        jScrollPane3.setViewportView(jTextAreaData);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 0.1;
        gridBagConstraints.weighty = 0.1;
        jPanel2.add(jScrollPane3, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 0.1;
        gridBagConstraints.weighty = 0.1;
        getContentPane().add(jPanel2, gridBagConstraints);
    }// </editor-fold>//GEN-END:initComponents

	private void jButtonGetInfoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonGetInfoActionPerformed
		startGetInfo();
	}//GEN-LAST:event_jButtonGetInfoActionPerformed

	private void jButtonSetDataActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonSetDataActionPerformed
		startSetDataAnswer();
	}//GEN-LAST:event_jButtonSetDataActionPerformed

	private void jButtonGetDataActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonGetDataActionPerformed
		startGetData();
	}//GEN-LAST:event_jButtonGetDataActionPerformed

	private void jButtonCallQueryActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCallQueryActionPerformed
		startCallQuery();
	}//GEN-LAST:event_jButtonCallQueryActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButtonCallQuery;
    private javax.swing.JButton jButtonGetData;
    private javax.swing.JButton jButtonGetInfo;
    private javax.swing.JButton jButtonSetData;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JSpinner jSpinnerQuery;
    private javax.swing.JTextArea jTextAreaAnswer;
    private javax.swing.JTextArea jTextAreaData;
    private javax.swing.JTextPane jTextPaneResponse;
    // End of variables declaration//GEN-END:variables
}