/** * Family Income Expendature Demonstrator * @author Robert J Morton YE572246C * @version 25 November 2001 revamped 16 November 2007 * Converted to a JFramed application Mon 27 Feb 2017 Open a terminal and change directory to where this file is loacated. To compile this program, enter the terminal command: javac income.java To run this program, enter the terminal command: java income */ import javax.swing.*; import java.awt.Dimension; // to be able to set the preferred JFrame size import java.awt.Color; // to be able to set JFrame background colour public class income extends JFrame { private static final long serialVersionUID = 701L; // what the hell this is for, I don't know! private static int XE = 545, // Horizontal extent of window and JFrame. 545 + 2 YE = 355, // Vertical extent of window and JFrame. 350 + 25 Xb = 2, // X-border thickness Yb = 30; // Y-border thickness, including title bar private static final String[] SW = {"-f","-j","-s"}; private static int LS[] = {0,1,2}, ls = 0, v = 0; // defaut view number private static String // default URL of the class, image and data files cb = "http://localhost/software/java_progs/graphs/", s; /* Declare a reference to an instance of the child class. Beware: an instance of the child class cannot be created here because this must be done within the invokeAndWait environment. */ private graphs child; private static final String // Title text for each possible view VIEW[] = { "Total Income","Utilities Costs","Taxation","Spendable Income", "Per Person Per Day","Budget Overspend","Mortgage Cost", "Car_Costs","Electricity Consumption","Electricity Cost", "Gas Energy Consumption","Gas Cost"}; private income() { // construct an instance of this extended JFrame super(VIEW[v]); // set window frame title on title bar /* Set up the window listener to listen for the window close command which occurs when the user clicks on the X control in the window's title bar.*/ setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); /* Set the initial size of the extended JFrame. This is the area INSIDE the frame. It does not include the border or the title bar areas. */ setPreferredSize(new Dimension(XE+Xb,YE+Yb)); setBounds(Xb,Yb,XE,YE); // of area inside window frame setBackground(Color.black); // default background colour of JFrame child = new graphs(XE,YE,ls,cb,v); // new instance of income class getContentPane().add(child); // add it to extended JFrame's pane pack(); // automatically pack to fill JFrame setVisible(true); // make this extended JFrame visible } public static void main(final String[] args) { if(argsValid(args)) { /* Initiate the creation of a new instance of this extended JFrame then wait until the building process has completely finished before giving the new instance of the child class permission to commence running.*/ try { javax.swing.SwingUtilities.invokeAndWait( new Runnable(){public void run(){new income();}}); } catch(Exception e) { System.out.println("Couldn't create Swing GUI."); System.out.println("There's probably an error in the constructor"); System.out.println("code of one of this class's child classes."); System.out.println(e); System.out.println(e.getCause()); } /* The above try-catch sequence is necessary for the following reason. The statement "new income();" is a request to Swing to create a GUI instance of this application. It includes, in effect, all the state- ments in the constructor methods of all this class's child classes. All these requests are made on this, the main() program thread. However, these requests are carried out [ie the actual constructing is done] by the underlying Swing system on the Event Despatching Thread. The constructing process necessarily takes longer to do than the mere task of REQUESTING that the constructing be done. This means that the main() thread will set the run() thread in motion before the GUI has finished being constructed. Hence trouble. The solution is to force the main() thread to withhold permission for the run() thread to start its job until the Event Despatching Thread has completely finished constructing the GUI. */ /* NOTE: This class inherits a paint() method from the JFrame class that it extends. This method automatically calls the paint() method of the child [extended JPanel] class when necessary. */ } // end of if(argsValid) } // end of main() /* RULE: For this app, the first switch must be present and must be a number between 0 and 12, which represents the required view. */ private static boolean argsValid(String[] args) { int L = args.length; // number of command-line arguments if(L == 0) return true; // if command line has no arguments s = args[0]; // the FIRST command line argument if((s.indexOf("help") != -1) || (s.indexOf("-h") != -1)) { System.out.println("First command line argument is a mandatory"); System.out.println("View Number between 0 and 11. The second is"); System.out.println("the Load Switch, which can have the values:"); System.out.println("-f = load files from local directory."); System.out.println("-j = load files from this app's jar file."); System.out.println("-s = load files from a specified server."); System.out.println("A URL may be entered after the -s switch."); System.out.println("If no URL is given, a default URL is used."); return false; } /* We already have the first argument in 's', which must, in this program, be a view number from 0 to 12. NOTE: char '0' = ASCII 48 */ int l = s.length(); // length of the entered view argument if(l > 0) { // if it contains at least one character v = getNum(0); // get that characters integer value if(l > 1) { // if it contains a second character v = v * 10; // multiply the first one by 10 v += getNum(1); // and add in the integer value of the second } } if(v < 0 || v > 11) v = 0; // safety valve if(L < 2) return true; // there is no second argument so use default s = args[1]; // get the SECOND argument /* See if this argument contains one of the valid switches "-f","-j","-s","-v". If it does, set ls = the switch index value, otherwise bail out with ls = 0 still. */ for(int i = 0; i < SW.length; i++) if(s.equals(SW[i])) { ls = i; break; } if(L < 3) return true; // no third argument so use default URL cb = args[2]; // there must be a THIRD arguement [URL] if(!cb.startsWith("http://")) { System.out.println("URL has absent or invalid protocol."); return false; } return true; } private static int getNum(int x){ int c = (int)(s.charAt(x)); if(c > 47 && c < 58) // if it's a character between '0' and '9' c -= 48; // get its numerical value else c = 0; return c; } } //end of income class