Initializing an Array from a GUI

 

Introduction.  Now I want to develop a more complicated example that will get scores from a GUI and compute their average when the user presses a button.  This will make use of passing arrays to methods, which you should remember are done pass by reference so that the original entries in the array are modified.

The program is also configured so that a user can enter how many scores they need.

The program also makes use of methods to do several things we have typically done elsewhere.  I've developed methods to

  • create the panel for input and output
  • get the grades from the GUI
  • compute the average and display it

Along with the usual methods

  • init( )
  • actionPerformed( )

This program is now getting to things that are more realistic.   You should call this Java applet AverageGrades.java.

 

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

public class AverageGrades extends JApplet implements ActionListener
{

String strNumberEntries;
int numberEntries;
// declaring an array to contain the scores
double testScores[];

// arrays of textfields for the inputs for each score
// and their average

JTextField txtGradeInput[];
JTextField txtAverageGrade = new JTextField();

// command button to cause computations to occur
JButton cmdCompute;

JPanel inputsOutputs = new JPanel();

public void init()
{

strNumberEntries = JOptionPane.showInputDialog("Please enter the number of grades");
numberEntries = Integer.parseInt(strNumberEntries);

// dynamically allocating the array at runtime
testScores = new double[numberEntries];
txtGradeInput = new JTextField[numberEntries];

// create input/output page
inputsOutputs = createInputPanel(numberEntries);

setContentPane(inputsOutputs);

}

// this is a method to create the layout for
// the user to fill in scores
// based on the number inputted

public JPanel createInputPanel( int numberRows )
{

int entryNumber;
// initializing the panel and its layout
JPanel panelGUI = new JPanel();
panelGUI.setLayout(new GridLayout(numberRows + 2, 2, 6, 6));

for (int k = 0; k < numberRows; k++)
{

entryNumber = k + 1;
panelGUI.add(new JLabel("Score " + entryNumber + ": ", SwingConstants.RIGHT));
txtGradeInput[k] = new JTextField(4);
panelGUI.add(txtGradeInput[k]);

}

panelGUI.add(new JLabel("Calculate Average: ", SwingConstants.RIGHT));
cmdCompute = new JButton("Compute");
cmdCompute.addActionListener(this);
panelGUI.add(cmdCompute);

panelGUI.add(new JLabel("The Average of the Grades: ", SwingConstants.RIGHT));
txtAverageGrade = new JTextField(4);
panelGUI.add(txtAverageGrade);

return panelGUI;

}

// the actionEvent handler
public void actionPerformed(ActionEvent userClick)
{

if (userClick.getSource( ) == cmdCompute)
{

getInputs(numberEntries, testScores);
computeAverage(numberEntries, testScores);

}

}

// get the inputs from the GUI
public void getInputs(int numberScores, double testScores[])
{

for (int j = 0; j < numberScores; j++)

testScores[j] = Double.parseDouble(txtGradeInput[j].getText());

}

// compute the average
public void computeAverage(int numberScores, double testScores[])
{

double averageOfGrades = 0.0;
for(int m = 0; m < numberScores; m++)

averageOfGrades = averageOfGrades + (testScores[m]/numberScores);

//  display the average in the appropriate text field
txtAverageGrade.setText(Double.toString(averageOfGrades));

}

}

 

The following listing is for AverageGrades.html.  We present it mainly to make sure you get a reasonable display on your first attempt.

 

<html>
<applet code="AverageGrades.class" width=330 height=400>
</applet>
</html>

 

Before we discuss this you should run it and get the output in the following self-explanatory image if you tell the program you have 5 scores to enter and you enter the same scores.

 

 

Code Discussion.  We will use our usual outline form to discuss the code.

  • import java.awt.*
  • import java.awt.event.*
  • import javax.swing.* for GUI compnents
  • declare the overall inclusive class AverageGrades to extend JApplet implement ActionListener
    • declare a string and integer to get number of scores to be entered from user
    • declare an array of doubles for testScores[ ]
    • declare an array of JTextFields for txtGradeInput[ ]
    • declare a JTextField for the txtAverageGrade
    • declare a JButton cmdCompute
    • declare a JPanel inputOutputs

     

  • declare method init( )
    • use showInputDialog( ) method of JOptionPane to get number of scores from the user
    • use parseInt( ) method of Integer class to convert the string to an integer numberEntries
    • use  numberEntries to dynamically allocate array for testScores
    • use  numberEntries to dynamically allocate array for JTextField txtGradeInputs
    • create the inputOutputs panel by returning the results of the createInputPanel( ) method while passing the number of scores to be averaged
    • declare and initialize an array of integers with a list
    • setContentPane for the applet to the inputOutputs panel

 

  • method createInputPanel( ) is declared and developed
  • returns a JPanel
  • it obtains a pass by value to the numberEntries used locally as numberRows
  • declare a variable entryNumber to be used to count the array elements in a more typical way
  • instantiate/construct a new JPanel( ) called panelGUI to hold our components
  • set the layout for this JPanel to be a GridLayout with 2 columns, cell padding of 6 pixels and number of rows that is two more than the number of scores
  • a for loop that runs from 0 up to just less than the numberRows
    • increment the entryNumber
    • put in a new label that will reflect the entryNumber
      • align it to the right of its cell
    • create the k-th element in the txtGradeInput array of JTextFields
    • add it to the GridLayout next to the appropriate label
  • instantiate/construct the cmdCompute JButton
  • add the ActionListener
  • add this button to the panelGUI
  • add another label for the average of the grades
    • align it to the right in its cell
  • instantiate a JTextField for the average of the scores
  • add this JTextField for the average of the scores to the panelGUI
  • return this panelGUI to be used as inputsOutputs

 

  • declare a method actionPerformed( ) to respond to the user's click on the cmdCompute
  • if cmdCompute is the source ofthe user's click then
    • use the getInputs( ) method to get what the user has entered for the scores
      • pass the int numberEntries
      • pass the array testScores by reference do it is updated by the method
    • compute the average using the computeAverage( ) method
      • pass the int numberEntries
      • pass the array testScores

 

  • method getInputs( ) is declared and developed
    • it requires the numberEntries to be passed by value into the local int numberScores
    • it requires the array of scores testScores[ ] to be passed in by reference to be referred to by the  same name locally
  • a for loop that runs through all the scores is used to
    • getText( ) from the appropriate txtGradeInput[ j ] JTextField
    • the parseDouble( ) method of the Double class is used to change the text entry to a double precision number and put it in the appropriate element in the array

 

  • method computeAverage( ) is declared and developed
    • it requires the numberEntries to be passed by value into the local int numberScores
    • it requires the array of scores testScores[ ] to be passed in by reference to be referred to by the  same name locally
  • a local averageOfGrades double precision variable is declared and initialized to zero
  • a for loop that runs through all the scores is used to
    • average the scores by dividing each by numberScores
    • adding it to the overall averageOfGrades
  • when done looping the averageOfGrades is
    • converted to a string using the toString( ) method in the Double class
    • written to the text field txtAverageGrade using the setText( ) method

 

You can change the grades in any of the text fields and compute the average whenever you want.  Unfortunately, I didn't put in any exception handling.  I figured there were enough new ideas in this code to merit not making it even more obscure.

Philosophies about how long methods should be in a class abound!