[Webfunds-commits] java/webfunds/client/contracts/wizard ContractEdit.java ContractFile.java FinishEnd.java FinishSig.java KeyContract.java KeyServer.java KeyTop.java Wizard.java WizardData.java WizardPanel.java iconnot.gif iconyes.gif

Edwin Woudt edwin@cypherpunks.ai
Tue, 8 Aug 2000 10:56:53 -0400 (AST)


edwin       00/08/08 10:56:53

  Modified:    .        Makefile
  Added:       webfunds/client/contracts/wizard ContractEdit.java
                        ContractFile.java FinishEnd.java FinishSig.java
                        KeyContract.java KeyServer.java KeyTop.java
                        Wizard.java WizardData.java WizardPanel.java
                        iconnot.gif iconyes.gif
  Log:
  Initial version of the sign contract wizard. Needs some cleanup.

Revision  Changes    Path
1.22      +2 -1      Makefile

Index: Makefile
===================================================================
RCS file: /home/webfunds/cvsroot/Makefile,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- Makefile	2000/08/08 07:11:19	1.21
+++ Makefile	2000/08/08 14:56:52	1.22
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile,v 1.21 2000/08/08 07:11:19 edwin Exp $
+# $Id: Makefile,v 1.22 2000/08/08 14:56:52 edwin Exp $
 #
 # This file was written by Jeroen C. van Gelderen and is in the public domain.
 
@@ -32,6 +32,7 @@
 		java/webfunds/client/plugins/*.java \
 		java/webfunds/client/sun/*.java \
 		java/webfunds/client/contracts/*.java \
+		java/webfunds/client/contracts/wizard/*.java \
 		java/webfunds/client/*.java
 
 build:



1.1                  java/webfunds/client/contracts/wizard/ContractEdit.java

Index: ContractEdit.java
===================================================================
/*
 * $Id: ContractEdit.java,v 1.1 2000/08/08 14:56:52 edwin Exp $
 *
 * Copyright (c) Systemics Inc 2000 on behalf of
 * the WebFunds Development Team.  All Rights Reserved.
 */

package webfunds.client.contracts.wizard;


import java.awt.*;
import javax.swing.*;


/**
 * Panel that allows the user to do final adjustments to the panel.
 *
 * @author Edwin Woudt <edwin@webfunds.org>
 * @version $Revision: 1.1 $
 */

public class ContractEdit extends WizardPanel {

    
    public JEditorPane editor;

    WizardData data;
    

    public ContractEdit(WizardData data) {
      
        this.data = data;
      
        // GridBagLayout is the most flexible (also the most difficult
        // to use) LayoutManager.
        GridBagLayout gridbag = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();

        setLayout(gridbag);
        
        
        // Define some components we'll use later on.
        JLabel     lab;


        // Ok, this is where the real dirty work starts. Do not attempt 
        // to change it, unless you understand the GridBagLayout and 
        // GridBagConstraints, because in case you don't the result 
        // will probably be a real f*ck up of the layout.
        
        c.gridheight = 1;      c.gridwidth = 1;
        c.gridy      = 0;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 5, 5);
        lab = new JLabel("Edit the contract"); 
        gridbag.setConstraints(lab,c); add(lab);
        
        
        c.gridheight = 1;      c.gridwidth = 1;
        c.gridy      = 1;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 1;
        c.fill       = GridBagConstraints.HORIZONTAL;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 15, 5);
        lab = new JLabel("<html><font size='-1'><b>"+
                         "In this step you can make any final adjustments to "+
                         "the contract."+
                         "</b></font></html>"); 
        gridbag.setConstraints(lab,c); add(lab);

        
        c.gridheight = 1;      c.gridwidth = 1;
        c.gridy      = 2;      c.gridx     = 0;
        c.weighty    = 1;      c.weightx   = 0;
        c.fill       = GridBagConstraints.BOTH;
        c.anchor     = GridBagConstraints.CENTER;
        c.insets     = new Insets(5, 5, 5, 5);
        editor = new JEditorPane();
        JScrollPane scroll = new JScrollPane(editor);
        gridbag.setConstraints(scroll,c); add(scroll);
        
    }
    
    
    public void enter() {
        editor.setText(data.getUnsignedContract());
    }
    
    public boolean leave() {
        return next();
    }

    public boolean next() {
        data.setUnsignedContract(editor.getText());
        return true;
    }


}


1.1                  java/webfunds/client/contracts/wizard/ContractFile.java

Index: ContractFile.java
===================================================================
/*
 * $Id: ContractFile.java,v 1.1 2000/08/08 14:56:52 edwin Exp $
 *
 * Copyright (c) Systemics Inc 2000 on behalf of
 * the WebFunds Development Team.  All Rights Reserved.
 */

package webfunds.client.contracts.wizard;


import java.io.DataInputStream;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


/**
 * Panel that asks for the filename of the contract.
 *
 * @author Edwin Woudt <edwin@webfunds.org>
 * @version $Revision: 1.1 $
 */

public class ContractFile extends WizardPanel 
                          implements ActionListener {

    JTextField txtFile;
    String oldFile = "";
    
    WizardData data;
    

    public ContractFile(WizardData data) {
      
        this.data = data;
        
        // GridBagLayout is the most flexible (also the most difficult
        // to use) LayoutManager.
        GridBagLayout gridbag = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();

        setLayout(gridbag);
        
        
        // Define some components we'll use later on.
        JButton    but;
        JLabel     lab;


        // Ok, this is where the real dirty work starts. Do not attempt 
        // to change it, unless you understand the GridBagLayout and 
        // GridBagConstraints, because in case you don't the result 
        // will probably be a real f*ck up of the layout.
        
        c.gridheight = 1;      c.gridwidth = 2;
        c.gridy      = 0;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 5, 5);
        lab = new JLabel("Read the contract file"); 
        gridbag.setConstraints(lab,c); add(lab);
        
        
        c.gridheight = 1;      c.gridwidth = 2;
        c.gridy      = 1;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 1;
        c.fill       = GridBagConstraints.HORIZONTAL;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 15, 5);
        lab = new JLabel("<html><font size='-1'><b>"+
                         "In this step you will choose the basic contract "+
                         "that you want signed. Choose Browse to search for a "+
                         "contract file. You will be able to make adjustments "+
                         "to the contract in the next screen. Skip this step "+
                         "if you want to copy/paste the contract without "+
                         "using a file."+
                         "</b></font></html>"); 
        gridbag.setConstraints(lab,c); add(lab);

        
        c.gridheight = 1;      c.gridwidth = 1;
        c.gridy      = 2;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 1;
        c.fill       = GridBagConstraints.HORIZONTAL;
        c.anchor     = GridBagConstraints.EAST;
        c.insets     = new Insets(5, 5, 5, 5);
        txtFile = new JTextField("");
        gridbag.setConstraints(txtFile,c); add(txtFile);


        c.gridheight = 1;      c.gridwidth = 1;
        c.gridy      = 2;      c.gridx     = 1;
        c.weighty    = 0;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 5, 5);
        but = new JButton("Browse"); 
        but.addActionListener(this);
        but.setActionCommand("browse");
        gridbag.setConstraints(but,c); add(but);
        

        // Filler, makes sure the whole thing is aligned to the top
        c.gridheight = 1;      c.gridwidth = 2;
        c.gridy      = 3;      c.gridx     = 0;
        c.weighty    = 1;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.CENTER;
        c.insets     = new Insets(5, 5, 5, 5);
        lab = new JLabel(""); 
        gridbag.setConstraints(lab,c); add(lab);
        
    }
    
    
    public void actionPerformed(java.awt.event.ActionEvent e) {
      
        if (e.getActionCommand().equals("browse")) {
          
            JFileChooser fc = new JFileChooser();
            
            fc.setDialogTitle("Open Contract");
            fc.setDialogType(fc.OPEN_DIALOG);
            fc.setFileSelectionMode(fc.FILES_ONLY);
            
            if (fc.showOpenDialog(this) == fc.APPROVE_OPTION) {
              
                try {
                    txtFile.setText(fc.getSelectedFile().getCanonicalPath());
                } catch (IOException ioe) { }
                            
            }
                      
        }
      
    }
    

    public void enter() {
        oldFile = txtFile.getText();
    }
    
    public boolean leave() {
        if (txtFile.getText() != oldFile) {
            return next();   // load the file
        } else {
            return true;
        }
    }

    public boolean next() {
        if (!txtFile.getText().equals("")) {
            try {
                FileInputStream fis = new FileInputStream(txtFile.getText());
                DataInputStream dis = new DataInputStream(fis);
                
                byte[] contr = new byte[fis.available()];
                dis.readFully(contr);
                
                String s = new String(contr,"ISO8859-1");
                data.setUnsignedContract(s);
                
                return true;
            } catch (IOException ioe) {
                String s;
                if (ioe instanceof FileNotFoundException) {
                    s = "File not found";
                } else {
                    s = ioe.toString();
                }
                JOptionPane.showMessageDialog(this, "Error opening file: "+s, 
                                            "Error", JOptionPane.ERROR_MESSAGE);
                return false;
            }
        } else {
            data.setUnsignedContract("");
            return true;
        }
    }


}


1.1                  java/webfunds/client/contracts/wizard/FinishEnd.java

Index: FinishEnd.java
===================================================================
/*
 * $Id: FinishEnd.java,v 1.1 2000/08/08 14:56:52 edwin Exp $
 *
 * Copyright (c) Systemics Inc 2000 on behalf of
 * the WebFunds Development Team.  All Rights Reserved.
 */

package webfunds.client.contracts.wizard;


import java.io.IOException;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


/**
 * Final 'congratulations' panel.
 *
 * @author Edwin Woudt <edwin@webfunds.org>
 * @version $Revision: 1.1 $
 */

public class FinishEnd extends WizardPanel {


    WizardData data;
        
    
    public FinishEnd(WizardData data) {
      
        this.data = data;
      
        // GridBagLayout is the most flexible (also the most difficult
        // to use) LayoutManager.
        GridBagLayout gridbag = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();

        setLayout(gridbag);
        
        
        // Define some components we'll use later on.
        JLabel     lab;


        // Ok, this is where the real dirty work starts. Do not attempt 
        // to change it, unless you understand the GridBagLayout and 
        // GridBagConstraints, because in case you don't the result 
        // will probably be a real f*ck up of the layout.
        
        c.gridheight = 1;      c.gridwidth = 1;
        c.gridy      = 0;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 5, 5);
        lab = new JLabel("Congratulations"); 
        gridbag.setConstraints(lab,c); add(lab);
        
        
        c.gridheight = 1;      c.gridwidth = 1;
        c.gridy      = 1;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 1;
        c.fill       = GridBagConstraints.HORIZONTAL;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 15, 5);
        lab = new JLabel("<html><font size='-1'><b>"+
                         "You now have a signed contract. "+
                         "The next steps now are to load WebFunds and check "+
                         "whether it accepts the contract and you can do a "+
                         "zero spend to yourself. If it doesn't: correct the "+
                         "errors and run this wizard again. If it does: good "+
                         "luck with your new contract. "+
                         "</b></font></html>"); 
        gridbag.setConstraints(lab,c); add(lab);

        
        // Filler, makes sure the whole thing is aligned to the top
        c.gridheight = 1;      c.gridwidth = 1;
        c.gridy      = 2;      c.gridx     = 0;
        c.weighty    = 1;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.CENTER;
        c.insets     = new Insets(5, 5, 5, 5);
        lab = new JLabel(""); 
        gridbag.setConstraints(lab,c); add(lab);
        
    }
    

    public void enter() {
        // do nothing
    }
    
    public boolean leave() {
        // do nothing
        return true;
    }

    public boolean next() {
        return true;
    }


}


1.1                  java/webfunds/client/contracts/wizard/FinishSig.java

Index: FinishSig.java
===================================================================
/*
 * $Id: FinishSig.java,v 1.1 2000/08/08 14:56:52 edwin Exp $
 *
 * Copyright (c) Systemics Inc 2000 on behalf of
 * the WebFunds Development Team.  All Rights Reserved.
 */

package webfunds.client.contracts.wizard;


import cryptix.openpgp.PGPException;
import cryptix.openpgp.PGPMessage;
import cryptix.openpgp.PGPPublicKey;
import cryptix.openpgp.PGPSecretKey;
import cryptix.openpgp.util.PGPArmoury;


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


/**
 * Panel that does the actual signing.
 *
 * @author Edwin Woudt <edwin@webfunds.org>
 * @version $Revision: 1.1 $
 */

public class FinishSig extends WizardPanel 
                         implements ActionListener {

    JTextField txtFile;
    
    WizardData data;
        
    
    public FinishSig(WizardData data) {
      
        this.data = data;
      
        // GridBagLayout is the most flexible (also the most difficult
        // to use) LayoutManager.
        GridBagLayout gridbag = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();

        setLayout(gridbag);
        
        
        // Define some components we'll use later on.
        JButton    but;
        JLabel     lab;


        // Ok, this is where the real dirty work starts. Do not attempt 
        // to change it, unless you understand the GridBagLayout and 
        // GridBagConstraints, because in case you don't the result 
        // will probably be a real f*ck up of the layout.
        
        c.gridheight = 1;      c.gridwidth = 2;
        c.gridy      = 0;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 5, 5);
        lab = new JLabel("Generating the Signature"); 
        gridbag.setConstraints(lab,c); add(lab);
        
        
        c.gridheight = 1;      c.gridwidth = 2;
        c.gridy      = 1;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 1;
        c.fill       = GridBagConstraints.HORIZONTAL;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 15, 5);
        lab = new JLabel("<html><font size='-1'><b>"+
                         "You have now collected all the information that is "+
                         "needed to sign the contract. Please specify the "+
                         "location where you want the signed contract to be "+
                         "stored. "+
                         "</b></font></html>"); 
        gridbag.setConstraints(lab,c); add(lab);

        
        c.gridheight = 1;      c.gridwidth = 1;
        c.gridy      = 2;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 1;
        c.fill       = GridBagConstraints.HORIZONTAL;
        c.anchor     = GridBagConstraints.EAST;
        c.insets     = new Insets(5, 5, 5, 5);
        txtFile = new JTextField("");
        gridbag.setConstraints(txtFile,c); add(txtFile);


        c.gridheight = 1;      c.gridwidth = 1;
        c.gridy      = 2;      c.gridx     = 1;
        c.weighty    = 0;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 5, 5);
        but = new JButton("Browse"); 
        but.addActionListener(this);
        but.setActionCommand("browse");
        gridbag.setConstraints(but,c); add(but);
        
        
        c.gridheight = 1;      c.gridwidth = 2;
        c.gridy      = 3;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 1;
        c.fill       = GridBagConstraints.HORIZONTAL;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 15, 5);
        lab = new JLabel("<html><font size='-1'><b>"+
                         "Press next to generate the signature. "+
                         "Please note that this process may take a while, "+
                         "depending on the speed of your computer. "+
                         "</b></font></html>"); 
        gridbag.setConstraints(lab,c); add(lab);
        

        // Filler, makes sure the whole thing is aligned to the top
        c.gridheight = 1;      c.gridwidth = 2;
        c.gridy      = 4;      c.gridx     = 0;
        c.weighty    = 1;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.CENTER;
        c.insets     = new Insets(5, 5, 5, 5);
        lab = new JLabel(""); 
        gridbag.setConstraints(lab,c); add(lab);
        
    }
    

    public void actionPerformed(java.awt.event.ActionEvent e) {
      
        if (e.getActionCommand().equals("browse")) {
          
            JFileChooser fc = new JFileChooser();
            
            fc.setDialogTitle("Open Contract");
            fc.setDialogType(fc.OPEN_DIALOG);
            fc.setFileSelectionMode(fc.FILES_ONLY);
            
            if (fc.showOpenDialog(this) == fc.APPROVE_OPTION) {
              
                try {
                    txtFile.setText(fc.getSelectedFile().getCanonicalPath());
                } catch (IOException ioe) { }
                            
            }
                      
        }
      
    }
    

    public void enter() {
        // do nothing
    }
    
    public boolean leave() {
        // do nothing
        return true;
    }

    public boolean next() {
        
        // parse the armoured key
        PGPArmoury akey;
        try {
            System.out.println(data.getSecretContractKey());
            akey = new PGPArmoury(data.getSecretContractKey());
        } catch (IllegalArgumentException iae) {
            error("Invalid contract key",iae);
            return false;
        }
        
        ByteArrayInputStream bais = new ByteArrayInputStream(akey.getPayload());
        DataInputStream dis = new DataInputStream(bais);
        
        
        // get the unarmoured secret key
        PGPSecretKey skey = new PGPSecretKey();
        try {
            skey.readKey(dis);
            // ### FIXME: when decryption is implemented, show a dialog box
            // ### for the password.
            // skey.decrypt("hoi");
        } catch (IOException ioe) {
            error("Error parsing contract key",ioe);
            return false;
        } catch (PGPException pe) {
            error("Error parsing contract key",pe);
            return false;
        }
        
        
        // put the contract together
        String all = data.getUnsignedContract();
        all = all + "\r\n[keys]";
        all = all + "\r\n\r\nkeys_contract='\r\n\r\n";
        all = all + data.getPublicContractKey();
        all = all + "\r\n'\r\n\r\nkeys_certification='\r\n\r\n";
        all = all + data.getTopLevelKey();
        all = all + "\r\n'\r\n\r\nkeys_server_certification='\r\n\r\n";
        all = all + data.getServerKey();
        all = all + "\r\n'\r\n\r\n[signatures]\r\n";
        

        // prepare and sign contract
        byte[] signedBytes;
            
        try {
            String signedContract = PGPMessage.clearSign(all, skey);
            signedBytes = signedContract.getBytes("ISO8859-1");
        } catch (IOException ioe) {
            error("PANIC: Error signing contract",ioe);
            return false;
        }

            
        // write the contract
        try {
            FileOutputStream fos = new FileOutputStream(txtFile.getText());
            DataOutputStream dos = new DataOutputStream(fos);
            dos.write(signedBytes);
        } catch (IOException ioe) {
            error("Error writing contract file",ioe);
            return false;
        }


        return true;
    }
    
    
    private void error(String message, Exception e) {
        e.printStackTrace();
        JOptionPane.showMessageDialog(this, message, "Error", 
                                      JOptionPane.ERROR_MESSAGE);
    }

}


1.1                  java/webfunds/client/contracts/wizard/KeyContract.java

Index: KeyContract.java
===================================================================
/*
 * $Id: KeyContract.java,v 1.1 2000/08/08 14:56:52 edwin Exp $
 *
 * Copyright (c) Systemics Inc 2000 on behalf of
 * the WebFunds Development Team.  All Rights Reserved.
 */

package webfunds.client.contracts.wizard;


import java.io.DataInputStream;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


/**
 * Panel that asks for the contract key
 *
 * @author Edwin Woudt <edwin@webfunds.org>
 * @version $Revision: 1.1 $
 */

public class KeyContract extends WizardPanel 
                         implements ActionListener {

    JTextField txtFile;
    JTextField txtFile2;
    String oldFile = "";
    
    WizardData data;
    
    
    public KeyContract(WizardData data) {
      
        this.data = data;
      
        // GridBagLayout is the most flexible (also the most difficult
        // to use) LayoutManager.
        GridBagLayout gridbag = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();

        setLayout(gridbag);
        
        
        // Define some components we'll use later on.
        JButton    but;
        JLabel     lab;


        // Ok, this is where the real dirty work starts. Do not attempt 
        // to change it, unless you understand the GridBagLayout and 
        // GridBagConstraints, because in case you don't the result 
        // will probably be a real f*ck up of the layout.
        
        c.gridheight = 1;      c.gridwidth = 2;
        c.gridy      = 0;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 5, 5);
        lab = new JLabel("Select the contract signing PGP key."); 
        gridbag.setConstraints(lab,c); add(lab);
        
        
        c.gridheight = 1;      c.gridwidth = 2;
        c.gridy      = 1;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 1;
        c.fill       = GridBagConstraints.HORIZONTAL;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 15, 5);
        lab = new JLabel("<html><font size='-1'><b>"+
                         "In this step you will choose the PGP key that will "+
                         "sign this contract. If you don't have one yet, then "+
                         "you should create one with your favourite PGP "+
                         "implementation. "+
                         "Make sure it is a DH/DSS or DSA/ElGamal key and "+
                         "that it is signed by the top-level issuer key. "+
                         "</b></font></html>"); 
        gridbag.setConstraints(lab,c); add(lab);

        
        c.gridheight = 1;      c.gridwidth = 2;
        c.gridy      = 2;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 5, 5);
        lab = new JLabel("The public key:"); 
        gridbag.setConstraints(lab,c); add(lab);
        
        
        c.gridheight = 1;      c.gridwidth = 1;
        c.gridy      = 3;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 1;
        c.fill       = GridBagConstraints.HORIZONTAL;
        c.anchor     = GridBagConstraints.EAST;
        c.insets     = new Insets(5, 5, 5, 5);
        txtFile = new JTextField("");
        gridbag.setConstraints(txtFile,c); add(txtFile);


        c.gridheight = 1;      c.gridwidth = 1;
        c.gridy      = 3;      c.gridx     = 1;
        c.weighty    = 0;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 5, 5);
        but = new JButton("Browse"); 
        but.addActionListener(this);
        but.setActionCommand("browse");
        gridbag.setConstraints(but,c); add(but);
        
        
        c.gridheight = 1;      c.gridwidth = 2;
        c.gridy      = 4;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 5, 5);
        lab = new JLabel("The secret key:"); 
        gridbag.setConstraints(lab,c); add(lab);
        
        
        c.gridheight = 1;      c.gridwidth = 1;
        c.gridy      = 5;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 1;
        c.fill       = GridBagConstraints.HORIZONTAL;
        c.anchor     = GridBagConstraints.EAST;
        c.insets     = new Insets(5, 5, 5, 5);
        txtFile2 = new JTextField("");
        gridbag.setConstraints(txtFile2,c); add(txtFile2);


        c.gridheight = 1;      c.gridwidth = 1;
        c.gridy      = 5;      c.gridx     = 1;
        c.weighty    = 0;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 5, 5);
        but = new JButton("Browse"); 
        but.addActionListener(this);
        but.setActionCommand("browse2");
        gridbag.setConstraints(but,c); add(but);
        
        
        c.gridheight = 1;      c.gridwidth = 2;
        c.gridy      = 6;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 5, 5);
        lab = new JLabel("Export instructions for PGP 6.5 on Windows:"); 
        gridbag.setConstraints(lab,c); add(lab);
        
        
        c.gridheight = 1;      c.gridwidth = 2;
        c.gridy      = 7;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 1;
        c.fill       = GridBagConstraints.HORIZONTAL;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 15, 5);
        lab = new JLabel("<html><font size='-1'><b>"+
                         "In PGPKeys, click with the right mouse button on "+
                         "key and select the 'Export' option. You will have "+
                         "to do this two times, once with and once without "+
                         "the private (secret) part of the key."+
                         "</b></font></html>"); 
        gridbag.setConstraints(lab,c); add(lab);
        

        // Filler, makes sure the whole thing is aligned to the top
        c.gridheight = 1;      c.gridwidth = 2;
        c.gridy      = 8;      c.gridx     = 0;
        c.weighty    = 1;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.CENTER;
        c.insets     = new Insets(5, 5, 5, 5);
        lab = new JLabel(""); 
        gridbag.setConstraints(lab,c); add(lab);
        
    }
    
    
    public void actionPerformed(java.awt.event.ActionEvent e) {
      
        if (e.getActionCommand().equals("browse")) {
          
            JFileChooser fc = new JFileChooser();
            
            fc.setDialogTitle("Open Contract");
            fc.setDialogType(fc.OPEN_DIALOG);
            fc.setFileSelectionMode(fc.FILES_ONLY);
            
            if (fc.showOpenDialog(this) == fc.APPROVE_OPTION) {
              
                try {
                    txtFile.setText(fc.getSelectedFile().getCanonicalPath());
                } catch (IOException ioe) { }
                            
            }
                      
        }
      
        if (e.getActionCommand().equals("browse2")) {
          
            JFileChooser fc = new JFileChooser();
            
            fc.setDialogTitle("Open Contract");
            fc.setDialogType(fc.OPEN_DIALOG);
            fc.setFileSelectionMode(fc.FILES_ONLY);
            
            if (fc.showOpenDialog(this) == fc.APPROVE_OPTION) {
              
                try {
                    txtFile2.setText(fc.getSelectedFile().getCanonicalPath());
                } catch (IOException ioe) { }
                            
            }
                      
        }
      
    }
    

    public void enter() {
        oldFile = txtFile.getText();
    }
    
    public boolean leave() {
        if (txtFile.getText() != oldFile) {
            return next();   // load the file
        } else {
            return true;
        }
    }

    public boolean next() {

        if (!txtFile.getText().equals("")) {
            try {
                FileInputStream fis = new FileInputStream(txtFile.getText());
                DataInputStream dis = new DataInputStream(fis);
                
                byte[] contr = new byte[fis.available()];
                dis.readFully(contr);
                
                String s = new String(contr,"ISO8859-1");
                data.setPublicContractKey(s);
                
            } catch (IOException ioe) {
                String s;
                if (ioe instanceof FileNotFoundException) {
                    s = "File not found";
                } else {
                    s = ioe.toString();
                }
                JOptionPane.showMessageDialog(this, "Error opening file: "+s, 
                                            "Error", JOptionPane.ERROR_MESSAGE);
                return false;
            }
        } else {
            data.setPublicContractKey("");
            return false;
        }

        if (!txtFile2.getText().equals("")) {
            try {
                FileInputStream fis = new FileInputStream(txtFile2.getText());
                DataInputStream dis = new DataInputStream(fis);
                
                byte[] contr = new byte[fis.available()];
                dis.readFully(contr);
                
                String s = new String(contr,"ISO8859-1");
                data.setSecretContractKey(s);
                
                return true;
            } catch (IOException ioe) {
                String s;
                if (ioe instanceof FileNotFoundException) {
                    s = "File not found";
                } else {
                    s = ioe.toString();
                }
                JOptionPane.showMessageDialog(this, "Error opening file: "+s, 
                                            "Error", JOptionPane.ERROR_MESSAGE);
                return false;
            }
        } else {
            data.setSecretContractKey("");
            return false;
        }

    }


}


1.1                  java/webfunds/client/contracts/wizard/KeyServer.java

Index: KeyServer.java
===================================================================
/*
 * $Id: KeyServer.java,v 1.1 2000/08/08 14:56:52 edwin Exp $
 *
 * Copyright (c) Systemics Inc 2000 on behalf of
 * the WebFunds Development Team.  All Rights Reserved.
 */

package webfunds.client.contracts.wizard;


import java.io.DataInputStream;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


/**
 * Panel that asks for the server certification key
 *
 * @author Edwin Woudt <edwin@webfunds.org>
 * @version $Revision: 1.1 $
 */

public class KeyServer extends WizardPanel 
                       implements ActionListener {

    JTextField txtFile;
    String oldFile = "";
    
    WizardData data;
    
    
    public KeyServer(WizardData data) {
      
        this.data = data;
      
        // GridBagLayout is the most flexible (also the most difficult
        // to use) LayoutManager.
        GridBagLayout gridbag = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();

        setLayout(gridbag);
        
        
        // Define some components we'll use later on.
        JButton    but;
        JLabel     lab;


        // Ok, this is where the real dirty work starts. Do not attempt 
        // to change it, unless you understand the GridBagLayout and 
        // GridBagConstraints, because in case you don't the result 
        // will probably be a real f*ck up of the layout.
        
        c.gridheight = 1;      c.gridwidth = 2;
        c.gridy      = 0;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 5, 5);
        lab = new JLabel("Select the transaction server PGP key."); 
        gridbag.setConstraints(lab,c); add(lab);
        
        
        c.gridheight = 1;      c.gridwidth = 2;
        c.gridy      = 1;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 1;
        c.fill       = GridBagConstraints.HORIZONTAL;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 15, 5);
        lab = new JLabel("<html><font size='-1'><b>"+
                         "In this step you will choose the server's PGP Key. "+
                         "You should have obtained it from your server "+
                         "operator. "+
                         "</b></font></html>"); 
        gridbag.setConstraints(lab,c); add(lab);

        
        c.gridheight = 1;      c.gridwidth = 1;
        c.gridy      = 2;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 1;
        c.fill       = GridBagConstraints.HORIZONTAL;
        c.anchor     = GridBagConstraints.EAST;
        c.insets     = new Insets(5, 5, 5, 5);
        txtFile = new JTextField("");
        gridbag.setConstraints(txtFile,c); add(txtFile);


        c.gridheight = 1;      c.gridwidth = 1;
        c.gridy      = 2;      c.gridx     = 1;
        c.weighty    = 0;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 5, 5);
        but = new JButton("Browse"); 
        but.addActionListener(this);
        but.setActionCommand("browse");
        gridbag.setConstraints(but,c); add(but);
        
        
        // Filler, makes sure the whole thing is aligned to the top
        c.gridheight = 1;      c.gridwidth = 2;
        c.gridy      = 5;      c.gridx     = 0;
        c.weighty    = 1;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.CENTER;
        c.insets     = new Insets(5, 5, 5, 5);
        lab = new JLabel(""); 
        gridbag.setConstraints(lab,c); add(lab);
        
    }
    
    
    public void actionPerformed(java.awt.event.ActionEvent e) {
      
        if (e.getActionCommand().equals("browse")) {
          
            JFileChooser fc = new JFileChooser();
            
            fc.setDialogTitle("Open Contract");
            fc.setDialogType(fc.OPEN_DIALOG);
            fc.setFileSelectionMode(fc.FILES_ONLY);
            
            if (fc.showOpenDialog(this) == fc.APPROVE_OPTION) {
              
                try {
                    txtFile.setText(fc.getSelectedFile().getCanonicalPath());
                } catch (IOException ioe) { }
                            
            }
                      
        }
      
    }
    

    public void enter() {
        oldFile = txtFile.getText();
    }
    
    public boolean leave() {
        if (txtFile.getText() != oldFile) {
            return next();   // load the file
        } else {
            return true;
        }
    }

    public boolean next() {
        if (!txtFile.getText().equals("")) {
            try {
                FileInputStream fis = new FileInputStream(txtFile.getText());
                DataInputStream dis = new DataInputStream(fis);
                
                byte[] contr = new byte[fis.available()];
                dis.readFully(contr);
                
                String s = new String(contr,"ISO8859-1");
                data.setServerKey(s);
                
                return true;
            } catch (IOException ioe) {
                String s;
                if (ioe instanceof FileNotFoundException) {
                    s = "File not found";
                } else {
                    s = ioe.toString();
                }
                JOptionPane.showMessageDialog(this, "Error opening file: "+s, 
                                            "Error", JOptionPane.ERROR_MESSAGE);
                return false;
            }
        } else {
            data.setUnsignedContract("");
            return true;
        }
    }


}


1.1                  java/webfunds/client/contracts/wizard/KeyTop.java

Index: KeyTop.java
===================================================================
/*
 * $Id: KeyTop.java,v 1.1 2000/08/08 14:56:52 edwin Exp $
 *
 * Copyright (c) Systemics Inc 2000 on behalf of
 * the WebFunds Development Team.  All Rights Reserved.
 */

package webfunds.client.contracts.wizard;


import java.io.DataInputStream;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


/**
 * Panel that asks for the toplevel certification key
 *
 * @author Edwin Woudt <edwin@webfunds.org>
 * @version $Revision: 1.1 $
 */

public class KeyTop extends WizardPanel 
                    implements ActionListener {

    JTextField txtFile;
    String oldFile = "";
    
    WizardData data;
    
    
    public KeyTop(WizardData data) {
      
        this.data = data;
      
        // GridBagLayout is the most flexible (also the most difficult
        // to use) LayoutManager.
        GridBagLayout gridbag = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();

        setLayout(gridbag);
        
        
        // Define some components we'll use later on.
        JButton    but;
        JLabel     lab;


        // Ok, this is where the real dirty work starts. Do not attempt 
        // to change it, unless you understand the GridBagLayout and 
        // GridBagConstraints, because in case you don't the result 
        // will probably be a real f*ck up of the layout.
        
        c.gridheight = 1;      c.gridwidth = 2;
        c.gridy      = 0;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 5, 5);
        lab = new JLabel("Select the top-level issuer PGP key."); 
        gridbag.setConstraints(lab,c); add(lab);
        
        
        c.gridheight = 1;      c.gridwidth = 2;
        c.gridy      = 1;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 1;
        c.fill       = GridBagConstraints.HORIZONTAL;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 15, 5);
        lab = new JLabel("<html><font size='-1'><b>"+
                         "In this step you will choose the top-level issuer "+
                         "PGP key. If you don't have one yet, then you should "+
                         "create one with your favourite PGP implementation. "+
                         "Make sure it is a DH/DSS or DSA/ElGamal key."+
                         "</b></font></html>"); 
        gridbag.setConstraints(lab,c); add(lab);

        
        c.gridheight = 1;      c.gridwidth = 1;
        c.gridy      = 2;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 1;
        c.fill       = GridBagConstraints.HORIZONTAL;
        c.anchor     = GridBagConstraints.EAST;
        c.insets     = new Insets(5, 5, 5, 5);
        txtFile = new JTextField("");
        gridbag.setConstraints(txtFile,c); add(txtFile);


        c.gridheight = 1;      c.gridwidth = 1;
        c.gridy      = 2;      c.gridx     = 1;
        c.weighty    = 0;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 5, 5);
        but = new JButton("Browse"); 
        but.addActionListener(this);
        but.setActionCommand("browse");
        gridbag.setConstraints(but,c); add(but);
        
        
        c.gridheight = 1;      c.gridwidth = 2;
        c.gridy      = 3;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 5, 5);
        lab = new JLabel("Export instructions for PGP 6.5 on Windows:"); 
        gridbag.setConstraints(lab,c); add(lab);
        
        
        c.gridheight = 1;      c.gridwidth = 2;
        c.gridy      = 4;      c.gridx     = 0;
        c.weighty    = 0;      c.weightx   = 1;
        c.fill       = GridBagConstraints.HORIZONTAL;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(5, 5, 15, 5);
        lab = new JLabel("<html><font size='-1'><b>"+
                         "In PGPKeys, click with the right mouse button on "+
                         "key and select the 'Export' option. Be sure NOT to "+
                         "include the private key. "+
                         "</b></font></html>"); 
        gridbag.setConstraints(lab,c); add(lab);
        

        // Filler, makes sure the whole thing is aligned to the top
        c.gridheight = 1;      c.gridwidth = 2;
        c.gridy      = 5;      c.gridx     = 0;
        c.weighty    = 1;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.CENTER;
        c.insets     = new Insets(5, 5, 5, 5);
        lab = new JLabel(""); 
        gridbag.setConstraints(lab,c); add(lab);
        
    }
    
    
    public void actionPerformed(java.awt.event.ActionEvent e) {
      
        if (e.getActionCommand().equals("browse")) {
          
            JFileChooser fc = new JFileChooser();
            
            fc.setDialogTitle("Open Contract");
            fc.setDialogType(fc.OPEN_DIALOG);
            fc.setFileSelectionMode(fc.FILES_ONLY);
            
            if (fc.showOpenDialog(this) == fc.APPROVE_OPTION) {
              
                try {
                    txtFile.setText(fc.getSelectedFile().getCanonicalPath());
                } catch (IOException ioe) { }
                            
            }
                      
        }
      
    }
    

    public void enter() {
        oldFile = txtFile.getText();
    }
    
    public boolean leave() {
        if (txtFile.getText() != oldFile) {
            return next();   // load the file
        } else {
            return true;
        }
    }

    public boolean next() {
        if (!txtFile.getText().equals("")) {
            try {
                FileInputStream fis = new FileInputStream(txtFile.getText());
                DataInputStream dis = new DataInputStream(fis);
                
                byte[] contr = new byte[fis.available()];
                dis.readFully(contr);
                
                String s = new String(contr,"ISO8859-1");
                data.setTopLevelKey(s);
                
                return true;
            } catch (IOException ioe) {
                String s;
                if (ioe instanceof FileNotFoundException) {
                    s = "File not found";
                } else {
                    s = ioe.toString();
                }
                JOptionPane.showMessageDialog(this, "Error opening file: "+s, 
                                            "Error", JOptionPane.ERROR_MESSAGE);
                return false;            }
        } else {
            data.setUnsignedContract("");
            return true;
        }
    }


}


1.1                  java/webfunds/client/contracts/wizard/Wizard.java

Index: Wizard.java
===================================================================
/*
 * $Id: Wizard.java,v 1.1 2000/08/08 14:56:52 edwin Exp $
 *
 * Copyright (c) Systemics Inc 2000 on behalf of
 * the WebFunds Development Team.  All Rights Reserved.
 */

package webfunds.client.contracts.wizard;


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.tree.*;


/**
 * Main class for the wizard
 *
 * @author Edwin Woudt <edwin@webfunds.org>
 * @version $Revision: 1.1 $
 */

public class Wizard extends JPanel 
                    implements TreeWillExpandListener, ActionListener {

    
    final WizardData data = new WizardData();
                            
    ImageIcon iconNot = new ImageIcon("iconnot.gif");
    ImageIcon iconYes = new ImageIcon("iconyes.gif");
    
    WizardPanel contractFile  = new ContractFile(data);
    WizardPanel contractEdit  = new ContractEdit(data);
    WizardPanel keyTop        = new KeyTop(data);
    WizardPanel keyContract   = new KeyContract(data);
    WizardPanel keyServer     = new KeyServer(data);
    WizardPanel finishSig     = new FinishSig(data);
    WizardPanel finishEnd     = new FinishEnd(data);
    
    WizardPanel[] wizardPanels  = { null, contractFile, contractEdit,
                                    null, keyTop, keyContract, keyServer,
                                    null, finishSig, finishEnd };
    int      wizardActive  = -1;
    int      wizardPrevAct = -1;
    
    boolean  usedNext = false;
    
    JTree tree;

    
    public Wizard() {
      
        // GridBagLayout is the most flexible (also the most difficult
        // to use) LayoutManager.
        GridBagLayout gridbag = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();

        setLayout(gridbag);
        
        // The content pane that contains the panels from all the steps.
        JPanel content = new JPanel();
        OverlayLayout layout = new OverlayLayout(content);
        content.setLayout(layout);

        boolean first = true;
        for (int i=0; i<wizardPanels.length; i++) {
            if (wizardPanels[i] != null) {
                if (first) {
                    wizardPanels[i].setVisible(true);
                    first = false;
                } else {
                    wizardPanels[i].setVisible(false);
                }
                content.add(wizardPanels[i]);
            }
        }

        
        // Ok, this is where the real dirty work starts. Do not attempt 
        // to change it, unless you understand the GridBagLayout and 
        // GridBagConstraints, because in case you don't the result 
        // will probably be a real f*ck up of the layout.
        
        c.gridheight = 3;      c.gridwidth = 1;
        c.gridy      = 0;      c.gridx     = 0;
        c.weighty    = 1;      c.weightx   = 1;
        c.fill       = GridBagConstraints.BOTH;
        c.anchor     = GridBagConstraints.CENTER;
        c.insets     = new Insets(8, 8, 8, 8);
        tree = createTree();
        tree.setBorder(BorderFactory.createEtchedBorder());
        gridbag.setConstraints(tree,c); add(tree);
        
        c.gridheight = 1;      c.gridwidth = 4;
        c.gridy      = 0;      c.gridx     = 1;
        c.weighty    = 1;      c.weightx   = 1;
        c.fill       = GridBagConstraints.BOTH;
        c.anchor     = GridBagConstraints.CENTER;
        c.insets     = new Insets(8, 8, 8, 8);
        gridbag.setConstraints(content,c); add(content);

        c.gridheight = 1;      c.gridwidth = 4;
        c.gridy      = 1;      c.gridx     = 1;
        c.weighty    = 0;      c.weightx   = 1;
        c.fill       = GridBagConstraints.BOTH;
        c.anchor     = GridBagConstraints.CENTER;
        c.insets     = new Insets(8, 8, 4, 8);
        JPanel pane = new JPanel();
        Color color = UIManager.getColor("Label.foreground");
        Border border = BorderFactory.createMatteBorder(0,0,1,0,color);
        pane.setBorder(border);
        gridbag.setConstraints(pane,c); add(pane);

        c.gridheight = 1;      c.gridwidth = 1;
        c.gridy      = 2;      c.gridx     = 1;
        c.weighty    = 0;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.WEST;
        c.insets     = new Insets(8, 8, 8, 8);
        JButton canc = new JButton("Cancel");
        gridbag.setConstraints(canc,c); add(canc);

        // Filler
        c.gridheight = 1;      c.gridwidth = 1;
        c.gridy      = 2;      c.gridx     = 2;
        c.weighty    = 0;      c.weightx   = 1;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.CENTER;
        c.insets     = new Insets(8, 8, 8, 8);
        JLabel lab = new JLabel(""); 
        gridbag.setConstraints(lab,c); add(lab);

        c.gridheight = 1;      c.gridwidth = 1;
        c.gridy      = 2;      c.gridx     = 3;
        c.weighty    = 0;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.EAST;
        c.insets     = new Insets(8, 8, 8, 4);
        JButton prev = new JButton("Previous");
        gridbag.setConstraints(prev,c); add(prev);

        c.gridheight = 1;      c.gridwidth = 1;
        c.gridy      = 2;      c.gridx     = 4;
        c.weighty    = 0;      c.weightx   = 0;
        c.fill       = GridBagConstraints.NONE;
        c.anchor     = GridBagConstraints.EAST;
        c.insets     = new Insets(8, 4, 8, 8);
        JButton next = new JButton("Next");
        gridbag.setConstraints(next,c); add(next);


        // Ensure that all three buttons have the same size
        Dimension dim1 = canc.getPreferredSize();
        Dimension dim2 = prev.getPreferredSize();
        Dimension dim3 = next.getPreferredSize();
        
        int max = dim1.width;
        if (dim2.width > max) max = dim2.width;
        if (dim3.width > max) max = dim3.width;
        
        dim1.width = max;
        dim2.width = max;
        dim3.width = max;
        
        canc.setMinimumSize(dim1);
        prev.setMinimumSize(dim2);
        next.setMinimumSize(dim3);
        
        // Get this class to listen for events
        canc.addActionListener(this);
        prev.addActionListener(this);
        next.addActionListener(this);

    }
    
    
    private JTree createTree(){
      
        DefaultMutableTreeNode root, lev1, lev2;
      
        root = new DefaultMutableTreeNode("Wizard");

        lev1 = new DefaultMutableTreeNode("Contract");
        root.add(lev1);
        lev2 = new DefaultMutableTreeNode("Read File");
        lev1.add(lev2);
        lev2 = new DefaultMutableTreeNode("Edit");
        lev1.add(lev2);

        lev1 = new DefaultMutableTreeNode("Keys");
        root.add(lev1);
        lev2 = new DefaultMutableTreeNode("Toplevel");
        lev1.add(lev2);
        lev2 = new DefaultMutableTreeNode("Contract");
        lev1.add(lev2);
        lev2 = new DefaultMutableTreeNode("Server");
        lev1.add(lev2);

        lev1 = new DefaultMutableTreeNode("Finish");
        root.add(lev1);
        lev2 = new DefaultMutableTreeNode("Signature");
        lev1.add(lev2);
        lev2 = new DefaultMutableTreeNode("Info");
        lev1.add(lev2);
        
        JTree tree = new JTree(root);
                
        // Tweak the display to remove the root object
        tree.setRootVisible(false);
        tree.setShowsRootHandles(false);
        
        // Show lines from the parents to the children
        tree.putClientProperty("JTree.lineStyle", "Angled");
        
        // Expand all rows. Doing this backwards is much more easy.
        tree.expandRow(2);
        tree.expandRow(1);
        tree.expandRow(0);
        
        // Prevent expand/collapse of nodes
        tree.addTreeWillExpandListener(this);
        
        // Fiddle in our own renderer which can show disabled nodes
        tree.setCellRenderer(new MyRenderer());

        // New Selectionmodel that does not allow invalid nodes to be
        // selected
        tree.setSelectionModel(new MySelectionModel());
        
        // Initial selection
        tree.setSelectionRow(1);
        
        return tree;
      
    }
    

    public void actionPerformed(ActionEvent e) {
      
        if (e.getActionCommand().equals("Next")) {
            
            if (wizardActive < wizardPanels.length-1) {
                data.setCompleted(wizardActive, true);
                int tmp = wizardActive + 1;
                if (wizardPanels[tmp] == null) tmp++;
                usedNext = true;
                tree.setSelectionRow(tmp);
            }
                
                      
        } else if (e.getActionCommand().equals("Previous")) {
          
            if (wizardActive > 1) {
                int tmp = wizardActive - 1;
                if (wizardPanels[tmp] == null) tmp--;
                tree.setSelectionRow(tmp);
            }
          
        }
      
    }

    public void treeWillExpand(TreeExpansionEvent e) 
                               throws ExpandVetoException {
        // No way dude, expanding/collapsing of nodes is disabled.
        throw new ExpandVetoException(e);
    }

    public void treeWillCollapse(TreeExpansionEvent e) 
                               throws ExpandVetoException {
        // No way dude, expanding/collapsing of nodes is disabled.
        throw new ExpandVetoException(e);
    }
    
    private class MyRenderer extends DefaultTreeCellRenderer {
      
        
        public Component getTreeCellRendererComponent(
                           JTree tree,
                           Object value,
                           boolean sel,
                           boolean expanded,
                           boolean leaf,
                           int row,
                           boolean hasFocus) {

            super.getTreeCellRendererComponent(
                            tree, value, sel,
                            expanded, leaf, row,
                            hasFocus);

            if (leaf) {
                if (data.getCompleted(row)) {
                    setIcon(iconYes);
                } else {
                    setIcon(iconNot);
                }
                if (data.getInvalid(row)) {
                    this.setEnabled(false);
                    setDisabledIcon(getIcon());
                }
            } else {
            } 

            return this;
        }
        
    }
    
    private class MySelectionModel extends DefaultTreeSelectionModel {
      
        
        public MySelectionModel() {
            
            setSelectionMode(SINGLE_TREE_SELECTION);
            
        }
        
        
        public void setSelectionPaths(TreePath[] pPaths) {
  
            TreePath path = pPaths[0];

            if (((TreeNode)path.getLastPathComponent()).isLeaf()) {

                RowMapper mapper = getRowMapper();
                TreePath[] ps = {path};
                int[] rows = mapper.getRowsForPaths(ps);

                if (!data.getInvalid(rows[0])) {
                    super.setSelectionPaths(ps);
                    wizardPrevAct = wizardActive;
                    wizardActive = rows[0];
                    if (wizardPrevAct != -1) {
                        wizardPanels[wizardPrevAct].setVisible(false);
                        if (usedNext) {
                            wizardPanels[wizardPrevAct].next();
                            usedNext = false;
                        } else {
                            wizardPanels[wizardPrevAct].leave();
                        }
                    }
                    wizardPanels[wizardActive].setVisible(true);
                    wizardPanels[wizardActive].enter();
                }

            }
            
        }

        
    }
    
    
    public static void main(String[] arg) {

        JFrame frame = new JFrame();
        frame.getContentPane().add(new Wizard());
        
        frame.setSize(640,450);
        frame.show();
        
    }



}


1.1                  java/webfunds/client/contracts/wizard/WizardData.java

Index: WizardData.java
===================================================================
/*
 * $Id: WizardData.java,v 1.1 2000/08/08 14:56:52 edwin Exp $
 *
 * Copyright (c) Systemics Inc 2000 on behalf of
 * the WebFunds Development Team.  All Rights Reserved.
 */

package webfunds.client.contracts.wizard;


/**
 * Contains most of data for the wizard.
 *
 * @author Edwin Woudt <edwin@webfunds.org>
 * @version $Revision: 1.1 $
 */

public class WizardData {

 
    private String unsignedContract  = "";
    private String toplevelKey       = "";
    private String publiccontractKey = "";
    private String secretcontractKey = "";
    private String serverKey         = "";
    private String signedContract    = "";
    
    
    public String getUnsignedContract  () { return unsignedContract;  }
    public String getTopLevelKey       () { return toplevelKey;       }
    public String getPublicContractKey () { return publiccontractKey; }
    public String getSecretContractKey () { return secretcontractKey; }
    public String getServerKey         () { return serverKey;         }
    public String getSignedContract    () { return signedContract;    }

    public void setUnsignedContract  (String x) { unsignedContract  = x; }
    public void setTopLevelKey       (String x) { toplevelKey       = x; }
    public void setPublicContractKey (String x) { publiccontractKey = x; }
    public void setSecretContractKey (String x) { secretcontractKey = x; }
    public void setServerKey         (String x) { serverKey         = x; }
    public void setSignedContract    (String x) { signedContract    = x; }


    private boolean[] invalid   = { false, false, false,
                                    false, false, false, false, 
                                    false, false, false };
    private boolean[] completed = { false, false, false,
                                    false, false, false, false,
                                    false, false, false };
                            
    public void setInvalid  (int row, boolean value) { invalid  [row] = value; }
    public void setCompleted(int row, boolean value) { completed[row] = value; }

    public boolean getInvalid   (int row) { return invalid  [row]; }
    public boolean getCompleted (int row) { return completed[row]; }

}


1.1                  java/webfunds/client/contracts/wizard/WizardPanel.java

Index: WizardPanel.java
===================================================================
/*
 * $Id: WizardPanel.java,v 1.1 2000/08/08 14:56:52 edwin Exp $
 *
 * Copyright (c) Systemics Inc 2000 on behalf of
 * the WebFunds Development Team.  All Rights Reserved.
 */

package webfunds.client.contracts.wizard;


import javax.swing.*;


/**
 * Abstract superclass for all panels in a wizard.
 *
 * @author Edwin Woudt <edwin@webfunds.org>
 * @version $Revision: 1.1 $
 */

public abstract class WizardPanel extends JPanel {
  
  
    /** 
     * Called by Wizard.java when entering this page
     */
    public abstract void enter();
    
    /** 
     * Called by Wizard.java when leaving this page when not using next.
     *
     * @return false when leaving this panel is not permitted, true otherwise.
     */
    public abstract boolean leave();

    /** 
     * Called by Wizard.java when leaving this page by using next
     *
     * @return false when leaving this panel is not permitted, true otherwise.
     */
    public abstract boolean next();

   
}