package Coop7t2;
//Title: Creative OO 7 : Threads / Concurrency
//Copyright: Copyright (c) 2001
//Author: John Fenton
//Company: LMU
//Description:Finally contains "the works".
import java.awt.*;
import java.awt.event.*;
import java.math.*;
public class ThreeX
{
public ThreeX()
{
ViewCl presentationObj = new ViewCl();
}
public static void main (String[] args)
{
ThreeX threeXObj = new ThreeX();
}
}
class ViewCl extends Frame
{
private ControllerCl dialogueObj;
private ModelCl applicationObj;
private Label lab1,lab2,lab3,lab4,lab5;
private GridBagLayout m;
private GridBagConstraints con;
private Panel pan1;
protected Checkbox cb1;
protected TextField tf1;
protected TextField tf2;
protected TextField tf3;
protected TextField tf4;
protected TextField tf5;
protected Button butStart;
protected Button butCancel;
protected Button butStop;
public ViewCl()
{
dialogueObj = new ControllerCl(this);
applicationObj = new ModelCl(this);
dialogueObj.getAppObj(applicationObj);
applicationObj.getDialObj(dialogueObj);
setSize(700,600);
setTitle("Three X Plus One Application");
drawInterface();
addWindowListener(new WindowAdapter()
{
public void windowClosing (WindowEvent we)
{
System.exit(0);
}
});
setVisible(true);
setCaret();
}
public void drawInterface()
{
m = new GridBagLayout();
pan1 = new Panel();
lab1 = new Label("Enter number to try:");
con = new GridBagConstraints();
con.gridx = 0;
con.gridy = 0;
con.gridwidth = GridBagConstraints.REMAINDER;
con.ipady = 20;
con.anchor = GridBagConstraints.WEST;
m.setConstraints(lab1,con);
tf1 = new TextField(50);
tf1.setEditable(true);
tf1.addActionListener(dialogueObj);
con.gridx = 0;
con.gridy = 1;
con.ipady = 5;
con.weightx = 0.5;
con.fill = GridBagConstraints.HORIZONTAL;
m.setConstraints(tf1,con);
butStart = new Button(" Start ");
butStart.addActionListener(dialogueObj);
con.gridx = 1;
con.gridy = 2;
con.gridwidth = 1;
con.fill = GridBagConstraints.NONE;
con.anchor = GridBagConstraints.WEST;
con.insets = new Insets(10,10,10,10);
m.setConstraints(pan1,con);
butStart.setBackground(new Color(192,255,192));
pan1.add(butStart);
butCancel = new Button("Cancel");
butCancel.addActionListener(dialogueObj);
butCancel.setBackground(new Color(192,192,224));
pan1.add(butCancel);
butStop = new Button(" Stop ");
butStop.addActionListener(dialogueObj);
butStop.setBackground(new Color(224,192,192));
pan1.add(butStop);
cb1 = new Checkbox("Automatically increment",false);
pan1.add(cb1);
con.insets = new Insets(0,0,0,0);
lab2 = new Label("Current number being tested : ");
con.gridx = 0;
con.gridy = 3;
con.ipady = 20;
con.gridwidth = GridBagConstraints.REMAINDER;
con.anchor = GridBagConstraints.WEST;
m.setConstraints(lab2,con);
tf2 = new TextField(50);
tf2.setEditable(false);
con.gridy = 4;
con.ipady = 5;
con.fill = GridBagConstraints.HORIZONTAL;
m.setConstraints(tf2,con);
lab3 = new Label("Largest number generated (on current number) so far: ");
con.gridy = 5;
con.ipady = 20;
con.gridwidth = GridBagConstraints.REMAINDER;
con.anchor = GridBagConstraints.WEST;
m.setConstraints(lab3,con);
tf3 = new TextField(50);
tf3.setEditable(false);
con.gridy = 6;
con.ipady = 5;
m.setConstraints(tf3,con);
lab4 = new Label("Smallest number generated (on current number) so far : ");
con.gridy = 7;
con.ipady = 20;
m.setConstraints(lab4,con);
tf4 = new TextField(50);
con.gridy = 8;
con.ipady = 5;
m.setConstraints(tf4,con);
lab5 = new Label("Total number of iterations : ");
con.gridy = 9;
con.ipady = 20;
con.gridwidth = GridBagConstraints.REMAINDER;
con.anchor = GridBagConstraints.WEST;
m.setConstraints(lab5,con);
tf5 = new TextField(50);
tf5.setEditable(false);
//con.gridx = 0;
con.gridy = 10;
con.ipady = 5;
m.setConstraints(tf5,con);
setLayout(m);
add(lab1);
add(tf1);
add(pan1);
add(lab2);
add(tf2);
add(lab3);
add(tf3);
add(lab4);
add(tf4);
add(lab5);
add(tf5);
}
public void setCaret()
{
tf1.setCaretPosition(0);
tf1.requestFocus();
}
public void clearStartingNumber()
{
tf1.setText("");
setCaret();
}
public String getData()
{
String s = tf1.getText();
return s;
}
}
class ControllerCl implements ActionListener
{
private ViewCl viewObj;
private ModelCl appObj;
public Thread workingThread1; //..............................(3)
public Thread workingThread2;
public ControllerCl(ViewCl vO)
{
viewObj = vO;
}
public void getAppObj(ModelCl mO)
{
appObj = mO;
}
public void actionPerformed(ActionEvent ae)
{
boolean validData;
if(ae.getSource() == viewObj.butStart)
{
validData = appObj.getAndValidateData();
if (validData == true)
{
appObj.initialise();
if (viewObj.cb1.getState() == true)
{
if (workingThread1 == null)
{
workingThread1 = new Thread(appObj,"Thread1");//................(4)
workingThread1.start(); //............................(5)
//appObj.repeatedlyCalculate();
}
}
else
{
workingThread2 = new Thread(appObj,"Thread2");
workingThread2.start();
}
}
}
if(ae.getSource() == viewObj.tf1)
{
String mess = "Please press the Start button when ready";
MessageDialogue md = new MessageDialogue(viewObj, mess);
md.show();
}
if(ae.getSource() == viewObj.butCancel)
{
viewObj.clearStartingNumber();
viewObj.setCaret();
}
if(ae.getSource() == viewObj.butStop)
{
appObj.stopProcessing();
if ((workingThread1 != null) && (workingThread1.isAlive()))
{
workingThread1 = null; //............................(6)
}
if ((workingThread2 != null) && (workingThread2.isAlive()))
{
workingThread2 = null; //............................(6)
}
}
}
}
class ModelCl implements Runnable //..................(1)
{
private String startingNumStr,biggestSoFarStr,smallestSoFarStr,itsStr,workingNumStr;
private BigInteger startingNumBI,biggestSoFarBI,smallestSoFarBI,workingBI;
private BigInteger copyOfBI,anotherCopyOfBI,itsBI;
private final BigInteger oneBI = BigInteger.ONE; //quicker without this?
private final BigInteger zeroBI = BigInteger.ZERO;
protected ViewCl viewObj;
protected ControllerCl dialObj;
private boolean carryOn;
public ModelCl(ViewCl vO)
{
viewObj = vO;
}
public void getDialObj(ControllerCl cO)
{
dialObj = cO;
}
public boolean getAndValidateData( )
{
try
{
startingNumStr = viewObj.getData( );
startingNumStr.trim();
if (startingNumStr.equals(""))
{
throw new NoDataException( );
}
}
catch (NoDataException nde)
{
String mess = "No data entered!";
MessageDialogue md = new MessageDialogue(viewObj, mess);
md.show();
return false;
}
try
{
startingNumBI = new BigInteger(startingNumStr);
}
catch (NumberFormatException nfe)
{
String mess = "Not a valid number";
MessageDialogue md = new MessageDialogue(viewObj, mess);
md.show();
return false;
}
int i = startingNumBI.signum();
if ( i < 1 )
{
String mess = "Must be a positive number greater than 0";
MessageDialogue md = new MessageDialogue(viewObj, mess);
md.show();
return false;
}
carryOn = true;
return true;
}
public void initialise()
{
viewObj.tf2.setText(startingNumStr);
biggestSoFarStr = startingNumStr;
viewObj.tf3.setText(biggestSoFarStr);
smallestSoFarStr = startingNumStr;
viewObj.tf4.setText(smallestSoFarStr);
biggestSoFarBI = startingNumBI;
smallestSoFarBI = startingNumBI;
workingBI = startingNumBI;
itsBI = zeroBI;
}
public void reinitialise()
{
workingBI = anotherCopyOfBI.add(oneBI);
workingNumStr = workingBI.toString();
viewObj.tf2.setText(workingNumStr);
biggestSoFarStr = workingNumStr;
viewObj.tf3.setText(biggestSoFarStr);
smallestSoFarStr = workingNumStr;
viewObj.tf4.setText(smallestSoFarStr);
biggestSoFarBI = workingBI;
smallestSoFarBI = workingBI;
itsBI = zeroBI;
}
public void stopProcessing()
{
carryOn = false;
}
public void run() //.....................................(2)
{
//calculate();
if (Thread.currentThread() == dialObj.workingThread1)
{
repeatedlyCalculate();
}
if (Thread.currentThread() == dialObj.workingThread2)
{
calculate();
}
}
public void repeatedlyCalculate()
{
calculate();
do
{
reinitialise();
calculate();
} while (carryOn == true);
}
public void calculate()
{
anotherCopyOfBI = workingBI;
while((workingBI.equals(oneBI) != true) && (carryOn == true))
{
copyOfBI = workingBI;
if((workingBI.testBit(0)) != false) //if bit0 not 0 it's odd
{
workingBI = workingBI.shiftLeft(1);
workingBI = workingBI.add(copyOfBI); //*3
workingBI = workingBI.add(oneBI); //+1
int comp = workingBI.compareTo(biggestSoFarBI);
if (comp == 1)
{
biggestSoFarBI = workingBI;
biggestSoFarStr = biggestSoFarBI.toString();
viewObj.tf3.setText(biggestSoFarStr);
}
}
else
{
workingBI = workingBI.shiftRight(1); // it's even so divide by 2
int comp = workingBI.compareTo(smallestSoFarBI);
if (comp == -1)
{
smallestSoFarBI = workingBI;
smallestSoFarStr = smallestSoFarBI.toString();
viewObj.tf4.setText(smallestSoFarStr);
}
}
itsBI = itsBI.add(oneBI);
itsStr = itsBI.toString();
viewObj.tf5.setText(itsStr);
//try
//{
// Thread.sleep(500); //allow user time to read data
//}
//catch(InterruptedException ie)
//{
//}
}
}
}
class NoDataException extends Exception
{
public NoDataException()
{
}
}
class MessageDialogue extends Dialog implements ActionListener
{
Button okBut;
Label messageLab,blank1,blank2;
public MessageDialogue(Frame parent, String message)
{
super(parent, "Error, error :", true); //true = modal
messageLab = new Label(message);
add(messageLab, BorderLayout.NORTH);
blank1 = new Label(" ");
add(blank1,BorderLayout.WEST);
blank2 = new Label(" ");
add(blank2, BorderLayout.EAST);
okBut = new Button("OK");
okBut.addActionListener(this);
add(okBut, BorderLayout.CENTER);
pack();
Point p = parent.getLocationOnScreen();
p.translate(parent.getSize().width/2-120,parent.getSize().height/2-50);
setLocation(p);
}
public void actionPerformed(ActionEvent ae)
{
setVisible(false);
}
}//end of program |