SeederDialog

Wouldn’t it be nice if there were a modal dialog that used a Seeder to generate a seed value? And wouldn’t it be nice if the dialog had a progress bar that showed how far along the generation was? I’ll develop this nice dialog now.

SeederDialog is designed to make it easy to integrate Seeder into your application. Create one, show it, and retrieve the seed value as follows:

SeederDialog sd = new SeederDialog(this, 20);
sd.show();
byte[] seed = sd.getSeed();

The dialog itself is shown in Figure 4.1. As the user types characters, the progress bar fills up. When the seed is fully generated, the dialog goes away.

SeederDialog in action
Figure 4-1. SeederDialog in action

SeederDialog is both an ActionListener and a KeyListener. It receives an ActionEvent from its Seeder when the seed is fully generated. It receives the same KeyEvents as the Seeder, which allows it to update the progress bar.

package oreilly.jonathan.awt;

import java.awt.*;
import java.awt.event.*;

import oreilly.jonathan.util.*;

public class SeederDialog
    extends Dialog
    implements ActionListener, KeyListener {

Internally, the dialog contains a Seeder object and a progress bar. (The progress bar is type oreilly.jonathan.awt.ProgressBar. I’ll present the code at the end of this section.)

  ProgressBar mProgressBar;
  Seeder mSeeder;

SeederDialog’s constructor accepts a parent Frame and a number of seed bytes. It creates itself as a modal dialog (true in the call to super()) and uses the setupWindow() method to configure the dialog.

  public SeederDialog(Frame parent, int seedBytes) {
    super(parent, "Seeder Dialog", true);
    setupWindow(seedBytes);
  }

The getSeed() method returns the seed value from the underlying Seeder object.

public byte[] getSeed() { return mSeeder.getSeed(); }

The dialog receives an ActionEvent from the Seeder when it is done. In this case, it simply shuts itself down.

public void actionPerformed(ActionEvent ae) { dispose(); }

SeederDialog receives the same KeyEvents that are sent to the Seeder. They are used to set the current level of the progress bar.

  public void keyPressed(KeyEvent ke) {}
  public void keyReleased(KeyEvent ke) {}
  public void keyTyped(KeyEvent ke) {
    mProgressBar.setLevel(mSeeder.getCurrentBitIndex());
  }

Finally, the setupWindow() method configures the user interface of the dialog and wires up the event handling.

  protected void setupWindow(int seedBytes) {
    setFont(new Font("TimesRoman", Font.PLAIN, 12));
    setLayout(new GridLayout(4, 1));
    Label t1 = new Label("Please type some keys");
    Label t2 = new Label("to initialize the random");
    Label t3 = new Label("number generator.");
    add(t1);
    add(t2);
    add(t3);
    mProgressBar = new ProgressBar();
    Panel p = new Panel();
    p.add(mProgressBar);
    add(p);
    
    setSize(200, 200);
    setLocation(100, 100);
    pack();
  
    mSeeder = new Seeder(seedBytes);
    mProgressBar.setMaximum(mSeeder.getBitLength());
    mSeeder.addActionListener(this);
    
    t1.addKeyListener(mSeeder);
    t1.addKeyListener(this);
    t1.requestFocus();
  }
}

As promised, here is the code for the progress bar that SeederDialog uses.

package oreilly.jonathan.awt;

import java.awt.*;

public class ProgressBar
    extends Canvas {
  int mLevel;
  int mMaximum;
  Color mFrameColor;

  public ProgressBar() { this(100); }
  
  public ProgressBar(int max) {
    setForeground(Color.blue);
    mFrameColor = Color.black;
    setMaximum(max);
    setLevel(0);
  }

  public void setMaximum(int max) {
    mMaximum = max;
    repaint();
  }
	
  public void setLevel(int level) {
    mLevel = (level > mMaximum) ? mMaximum : level;
    repaint();
  }

  public void update(Graphics g) { paint(g); }
	
  public void paint(Graphics g) {
    Dimension d = getSize();
    double ratio = (double)((double)mLevel / (double)mMaximum);
    int x = (int)((double)d.width * ratio);

    g.setColor(mFrameColor);
    g.drawRect(0, 0, d.width - 1, d.height - 1);

    g.setColor(getForeground());
    g.fillRect(1, 1, x, d.height - 2);
            
    g.setColor(getBackground());
    g.fillRect(x + 1, 1, d.width - 2 - x, d.height - 2);
  }
	           
  public Dimension getMinimumSize() { return new Dimension(10, 1); }
  public Dimension getPreferredSize() { return new Dimension(100, 10); }
}
             
             
            

Get Java Cryptography now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.