Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

JVM Languages

Incrementally Updating Software


SimpleMortgageCalculator() {
  super();
  this.setUndecorated(true);
  //this is where the settings from the last use are retrieved
  try{
    applicationProperties.load(new FileInputStream(CALCULATOR_CONFIG_FILE));
  }
  catch(Exception ex){
    System.out.println("problem loading properties 
                                     file on startup "+ex.toString());
  }
  // Add the window listener 
  addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent evt) {
      dispose(); 
      System.exit(0); 
  }});

  addMouseListener(this);
  addMouseMotionListener(this);

  //don't want this resizable, as it makes the background look odd
  this.setResizable(false);

  buttons=new Button[4];//calculate, skins, languages, quit
  fields=new TextField[4];//Amount, Interest Term, Length in years, Results
  labels=new Label[4];//Amount, Interest Term, Length in years, Results

  buttons[CALCULATE]=new Button("");//calculate
  buttons[SKINS]=new Button("");//skins
  buttons[LANGUAGES]=new Button("");//languages
  buttons[QUIT]=new Button("");//quit
  buttons[CALCULATE].addActionListener(this);
  buttons[SKINS].addActionListener(this);
  buttons[LANGUAGES].addActionListener(this);
  buttons[QUIT].addActionListener(this);
  this.add(buttons[CALCULATE]);
  this.add(buttons[SKINS]);
  this.add(buttons[LANGUAGES]);
  this.add(buttons[QUIT]);

  fields[AMOUNT]=new TextField(15);//amount
  fields[INTEREST]=new TextField(6);//interest
  fields[TERM]=new TextField(4);//term in years
  fields[RESULTS]=new TextField(10);//results
  this.add(fields[AMOUNT]);
  this.add(fields[INTEREST]);
  this.add(fields[TERM]);
  this.add(fields[RESULTS]);

  labels[AMOUNT]=new Label("");//amount
  labels[INTEREST]=new Label("");//interest
  labels[TERM]=new Label("");//terms
  labels[RESULTS]=new Label("");//results
  this.add(labels[AMOUNT]);
  this.add(labels[INTEREST]);
  this.add(labels[TERM]);
  this.add(labels[RESULTS]);

  //this is where the last skin and language are reloaded
  String lastSkin=applicationProperties.getProperty(LAST_SKIN_PROPERTY);
  String lastLanguage=
              applicationProperties.getProperty(LAST_LANGUAGE_PROPERTY);
  if(lastSkin==null) lastSkin="downtown.jar";
  if(lastLanguage==null) lastLanguage="english.properties";
  SkinLoader.getInstance().loadNewSkin(lastSkin);
  LanguageLoader.getInstance().loadNewLanguage(this, lastLanguage);
  Dimension d=SkinLoader.getInstance().getSize();
  setSize((int)d.getWidth(), (int)d.getHeight());
  //Center the window
  Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize();
  Rectangle winDim = getBounds();
  setLocation((screenDim.width - winDim.width) / 2,
         (screenDim.height - winDim.height) / 2);
  setVisible(true);
  //need a visible window to render the image onto.
  backgroundImage = SkinLoader.getInstance().getImage(this);
  SkinLoader.getInstance().addWidgets(this, buttons, fields, labels);
}
Listing One: SimpleMortgageCalculator.
public void actionPerformed(ActionEvent e){
  if(e.getSource()==buttons[CALCULATE]){//calculate button
    double dResult=Calculate.crunch(fields[AMOUNT].getText(), 
                    fields[INTEREST].getText(), fields[TERM].getText());
    if(dResult>0.0){
      fields[RESULTS].setText(""+(int)dResult);
    }
    else{
      fields[RESULTS].setText(LanguageLoader.
                               getInstance().lookUpString("badresult"));
    }
  }
  else if(e.getSource()==buttons[SKINS]){//skins button
    SkinLoader.getInstance().chooseSkin(this); 

    //size is in the skin
    Dimension d=SkinLoader.getInstance().getSize();
    setSize((int)d.getWidth(), (int)d.getHeight());
    //as is the image
    backgroundImage = SkinLoader.getInstance().getImage(this);
    //and the display area    
    this.paint(this.getGraphics());
    //add controls
    SkinLoader.getInstance().addWidgets(this, buttons, fields, labels);
  }
  else if(e.getSource()==buttons[LANGUAGES]){//languages
    LanguageLoader.getInstance().chooseLanguage(this); 
  }
  else if(e.getSource()==buttons[QUIT]){//quit button
    try{
      //remember what the last skin and language were
      String lastSkin=SkinLoader.getInstance().getCurrentSkin();
      String lastLanguage=LanguageLoader.getInstance().getCurrentLanguage();
      applicationProperties.setProperty(LAST_SKIN_PROPERTY, lastSkin);
      applicationProperties.setProperty(LAST_LANGUAGE_PROPERTY, lastLanguage);
      applicationProperties.
              store(new FileOutputStream(CALCULATOR_CONFIG_FILE), 
                                  "SimpleMortageCaculator properties file");
    }
    catch(Exception ex){
      System.out.println("problem storing properties 
                                          file on shutdown "+ex.toString());
    } 
    //write out the configuration file, then quit
    exit();
  }
}
Listing Two: actionPerformed method.
  public void loadComponent(String skinFile){
    try{
      URL u = new URL("jar:file:skins/"+skinFile+"!/");
      int index=skinFile.indexOf(".jar");
      String thisClass=skinFile.substring(0, index);
      String strClass="skins."+thisClass;//jar and main class files match
      ucl = new URLClassLoader(new URL[] { u });
      c= (Class) Class.forName(strClass, true, ucl);
      m = c.getMethod(SKIN_METHOD, SKIN_METHOD_ARGS);
      currentSkin=skinFile;
      image=null;
    }
    catch(Exception ex){
      System.out.println("exception in SkinLoader.loadComponent()
"+ex.toString());
    }
  }
Listing Three: loadComponent method.
//bundling a dimension for a call to the skin to get the dimension
Object oa[]=new Object[1];
oa[0]=new Dimension();
Integer IReturn=(Integer)m.invoke(c, new Object[] {oa, new Integer(1), new Integer(1) });
d=(Dimension)oa[0];
Listing Four: Bundling in SkinsLoader.
//fragment from the skinMethod in the skin where arguments are unbundled
  public static Integer skinMethod(Object [] args, Integer callType, Integer callerVersion){
     
    int type=callType.intValue();

    switch(type){
      case 1://call for size of the window
        return new Integer(getSize((Dimension)args[0]));

//The getSize method in the skin sets the dimensions and then returns OK.

  private static int getSize(Dimension d){
    d.setSize(500, 300);
    return OK;
  }
Listing Five: Unbundling in the skin.

//code called in LanguageLoader to load the current language
  public static void loadNewLanguage(String languageFile){
    languageChangedFlag=true;
    properties.clear();
    try{
      properties.load(new FileInputStream("languages/"+languageFile));
    }
    catch(IOException ioe){
      System.out.println("problem loading language file "+ioe.toString());
    }
    frame.paint(frame.getGraphics());
  }
Listing Six: loadNewLanguage method.

if (e.getSource()==list) {
  // When the user double-clicks on a component, try to load it
  if (e.getID() == Event.ACTION_EVENT) {
    String strFile=list.getSelectedItem();
    ComponentInfo ci=(ComponentInfo)hashComponents.get(strFile);
      
    //if the component is not yet on the file system, download it
    if(!ci.getDownloaded()){
      this.setTitle("Downloading "+ci.getFileName());
      RemoteComponentLoader.requestComponent(ci.getLocation(), 
                                directory+"/"+ci.getFileName());
    }
    loader.loadComponent(strFile);  
    this.dispose();
  }
}
Listing Seven: Loading a component.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.