Monday, April 1, 2013

UNIT F -- A "Hello World," functional foundation for Java- based Programming

XXXX

NB: WORK IN PROGRESS . . .
(A proof of concept sampler) 

(NOTE: There is an in a nutshell overview by Matloff, here. For a complete intro to Java text ver 7 by Eck, kindly cf here. Onwards, he has a computer graphics coursebook, cf here. In both cases, make sure to go to his preface and link to the book web page for all sorts of resources. Eck's Foundations of Computation, here, may also be helpful. Note the video tutorial series here. The more textual one here may help, and the more detailed video tutorials here. This 34 minute overview single session may be useful too.)



FOCUS:
Programming, hello world Java Programming, hello world Java (also cf. here for a step by step tutorial approach) and the wider framework of programming by select examples (Dr Java lightweight compiler?  Cf e-textbook here and Moodle online course approach here, also the in a nutshell here.)  Programs as coded algorithms (step by step recipes) and the data structures (& storage) they use, thus the basic I --> P --> O information processing model: initialisation --> input, processing (step by step) & storage, output. Stuctures: sequence, branches, loops. First steps to windows, with Automatic Windowing Toolkit (AWT) etc.


____________________

CONTENTS






Introduction: The first thing is to get our feet wet. Programming is in the end a practical activity, so let's start with some hello world based case studies. After this foundation unit or tutorial/ workshop, you should be comfortable enough to know how to set up, key in, run and compose a simple program that uses the main control structures. You should also have a place to begin building proficiency and then expertise. That brings up a question of basic understanding:


Programming is . . . 


Programming can be seen as the coding of algorithms acting on data in structures.

That is: 
a --> there is a programming language (such as Java) that

b --> allows us -- prospective programmers -- to instruct a certain machine (the computer) to carry out in specific detail, just how certain step- by- step procedures (i.e. algorithms)  solve particular problems or achieve given goals

c --> by acting on data (which in the objects view, collectively defines the state of some entity on the software stage), where also

d --> such data must be put in an agreed, standardised coded form and stored in an organised, retrievable way. 

e --> The instructions that process the data are coded as well, in a computer language, such as Java or Assembly Language or -- for actual execution -- the 1's and 0's of the specific Machine Language of a particular processor. 
f --> Where, as is discussed in Unit B, we may picture the modern computer as resting on a physical, electronics technology based physical hardware machine that implements a digital information processor with its machine language (abstracted from voltages like 0 - 0.7 V for 0 and 2.4 - 5 V for 1 for, for example, classic TTL logic circuits). The heart of that machine is the Central Processing Unit or CPU, which functions by fetching, decoding and executing Instructions. As David and Paul Gries summarise in their Multimedia Introduction to Computing, using Java textbook (p. 5): 
g -->  Where, a "typical" CPU built on a chip [= Microprocessor Unit, MPU], the Intel 8086 (an early, 16 bit register member of the Pentium Family) is organised like this:
An example of the architecture of a CPU, the 8086. Cf. an example of Machine & Assembly programming, here.
(Often, there is a yet lower level of coding that executes (some) machine instructions,
i.e. microcode, vs. hard-wired processors. Hard-wiring is faster, microcode more flexible.)
. . . such lives on a motherboard, which may be simply represented:

h --> However such is not very easy to work with without years of Electronics Engineering and/or Computer Science education or the like, so we will instead use a layer-cake of ever more abstract virtual machines that builds up to applications with today's "intuitive" Graphical and/or Touch Screen User Interfaces:

i --> Now, apart from specialist programming that needs to address more machine-specific aspects (such as for device drivers, or to create an operating system or to develop compilers or interpreters for "high level languages" [e.g. COBOL, Fortran, Pascal, Basic, C, Java, Python, Ruby on Rails etc]), modern programming addresses high-level virtual machines. Indeed,

j --> . . . for decades, there has been a trend to create cross-platform virtual machines so that (often more in principle than in reliable reality!) we have WORA . . . write once, run anywhere. (And of course, user interfaces include those faced by programmers, such as Integrated Development Environments, IDE's.)

As David and Paul Gries explained:
Computers do not speak English. Instead, they have a rather peculiar communi-
cation  system  involving  electric  signals  carried  through  silicon,  etched  using
acids and electric current. Despite this rather alien and complex nature, humans
still manage to create incredibly useful virtual tools using computers. (A hammer
is real. A spreadsheet is virtual. You will not be able to pick up and hold anything
that you learn how to build during your introductory programming course or, in
fact, during your entire career as a programmer.)

A program is a set of instructions for a computer to follow. Over half a cen-
tury ago, the first computer programs were created rather tediously, by plugging
wires  into  sockets  in  intricate  patterns.  Flashing  lights  were  used  to  indicate
results.  In  the  first  programming  courses,  students  would  write  a  program  on
“paper tape” or “punch cards” and then submit the tape or deck of cards for pro-
cessing. A few hours later, or even more, they would see the results of running the
program and get their tape or cards back. Today, programs are created using a
keyboard,  or  even  automatically  generated  using  drawing  tools,  and  executed
immediately. In a few seconds, you see the results. What a difference! [Multimedia Introduction to Computing, using Java (Springer, 2005), Ch 0, "Computers and Programming," p. 3. NB: They go on to highlight the significance of Dr Java, an educational Integrated Development Environment created by Rice University.]

   The art of programing, then, is that of learning/knowing how to effectively and efficiently develop code that correctly processes the relevant, well-organised data. That code typically sets out sequenced lists of instructions carried out on data when the parts of programs are called into action. Such processing usually takes in inputs, carries out processing and gives out outputs. Hence, the IPO framework for computing:


Unfortunately, that need for detailed, specific step by step verbal description and instruction makes programming difficult in many cases. It is easy to make a mistake or fail to anticipate particular circumstances that can cause trouble, and it has been said that no complex program is or can be absolutely bug free. And, in today's world of hackers looking for gaps to exploit, to take over not only PCs but even things like printers to do all sorts of destructive things, that is a further challenge.

The goal of this course, then, is to help us develop the art of programming (with an emphasis on Java as main language used) to first, basic ABC-123 level proficiency. Afterwards, we can build on that basic proficiency to attain expertise in particular areas of interest, but we must start somewhere.

Here, is about as good a place and time as any.

A 34-minute Java introduction:



Now, back in the 1960's a major theorem of computer science [roughly: the science that studies computing and the machines that compute] was proved. It is so important that it is where we need to begin.

The theorem sounds almost like glorified common sense: 

Any computable process or function can be organised based on three structures:
(a) step-by-step sequences,
(b) selections between alternative sequences and
(c) iterations or loops of sequences. 

(This is called the structured programming theorem, or sometimes the Böhm- Jacopini theorem after the two men who proved and championed it. [Believe it or not, it was controversial at the time! For years, people would put up particularly twisty bits of code and challenge others to reduce them to structured form. It can always be done. Might be hard to figure out (which also means that the twisty, tangled "spaghetti code" will be typically hard to maintain or effectively modify . . . ), but it is do-able.])

One trick to effectively using these structures, is that it is important to make sure that each structure has just one normal entry point and just one normal exit, which helps us modularise programs. No spaghetti code needed or wanted here!

Joost illustrates nicely:



Wikipedia, as just linked:
Spaghetti code is a pejorative term for source code that has a complex and tangled control structure, especially one using many GOTO statements, exceptions, threads, or other "unstructured" branching constructs. It is named such because program flow is conceptually like a bowl of spaghetti, i.e. twisted and tangled. Spaghetti code can be caused by several factors, including inexperienced programmers blindly obeying their supervisors' mandates on how to write code and a complex program which has been continuously modified by several people over a long life cycle. Structured programming greatly decreased the incidence of spaghetti code.

Where, "normal" entry and exit points to one of the underlying challenges: exception handling for error conditions of various sorts.

And of course, the objects approach carries this to the next level, where we cluster our coding into collections of interacting objects that have a state defined by data and methods that allow us to access and modify the state as the program acts.

As a further reminder from Unit B, let us reflect again on the MVC-DCI "software stage viewed through a software window" framework, which (instructively) invites us to see programming as in effect scriptwriting for an interactive software play where the user plays a role:

Fig. F.1: The MVC-DCI framework

 A simple, classic way to visualise how the three main structures (and a fourth derivative one, the CASE structure) work, is to use the traditional flowchart:

Fig. F.2: The major structured programming patterns, sequence, branch, loop: with a subsidiary one, case.(The case structure is equivalent to a ladder of IF/ELSE branches. The decision node has been "stretched." There are various possible loop structures, e.g. consider what happens if the process sequence does the "steps" before the decision on repeating or exiting.)
In short:
a -->  sequences are steps of a "recipe" taken in turn, one after the other that allow us to follow the steps that help us "bake the cake." Where,

b --> branches allow automated decision-making or responses to conditions, so that which of alternative paths of steps is taken is decided based on a test, and

c --> looping allows the same set of instructions to be done over and over while or until a condition is met, or for a counted off number of cycles. (It has been said that (as can easily be imagined) maybe 80% of program execution time is spent in loops.)
NB: we may decide before we take the steps, to do procedure steps X until a condition C is made, or while the condition C holds. This option means that we need not do the steps at all. If the steps come before the looping test, then we will do the steps X at least once, for the obvious reason.

d --> the fourth structure -- CASE -- is an extension of the branching one, where different outcomes are chosen depending on different possible values (cases) of a "switch."
(Logically, such is equivalent to having a sequence of decision nodes in a "ladder" in the case/switch block in panel 4, that one climbs down step by step. The first test takes in case a and switches processing to the process for alt. a; the second, does so for b, etc; and on in succession to n. If any of cases a, b, etc. hold, the program therefore executes that case, and if not it falls through the ladder to a default. There may be an exception handling procedure required as well, for safety.)
Such procedures occur in the context of a software system. That means there is a process logic involved. Typically:
1: Initialise the system to a known baseline condition, on start-up, reboot or being called by something else. Often, this requires masking off inputs until things are settled down, lest the system goes out of control. Then as baseline is achieved, the system is released to accept inputs.

2: Scan for, or listen to, inputs and take them in, probably initially conditioning and storing them in a known register in a specific organised format.

3: This may require exception handling, where special "routines" are called to handle errors or other exceptions, to guard against going out of control based on nonsense inputs, or breakdowns in processing or outputs, or emergencies, etc. Users may be prompted to confirm that given inputs echoed to them, are good.

4: Once required inputs are present, they are processed and transformed using step- by- step procedures -- algorithms, to form the results. Again such are stored in an appropriate format in an appropriate location.

5: With valid results in hand, required outputs are generated and communicated to the user or other destination, perhaps triggering onward inputs.

6: The system releases resources, or gets ready for onward processing otherwise.
A classic technique for analysing what is involved in such process logic (and which is very useful generally), is the use of a "work breakdown structure," in this context called a HIPO Chart. That is, a hierarchy of input/ processing/ output chart:

Fig. F.3: A HIPO work breakdown structure chart, shown in a way that emphasisies the classic I --> P --> O pattern. It may pay to use the more elaborate initialise, input, handle exceptions, process output, release pattern as described above.  It is always helpful to understand what is going on in terms of work to be done. It then helps to think in terms of the software window viewing and interacting with software objects on a stage that carry out the tasks in hand, the MVC - DCI context of Fig. F.1 above.


Such a framework of processing and structured step by step procedures, does not go away now that we deal with objects interacting as actors on a software stage viewed and interacted with through a software window. Just, the processing and data are encapsulated within the object, in significant part, in order to avoid so-called spaghetti programs that have many tightly coupled and interdependent inter-connexions running all over the place. Creating a snowballing maintenance nightmare.

And, actually, this has long since been known.

Here is a clip on the information-hiding principle of modular programming from a classic text I used in designing systems coded at assembly/machine language level, back in the 1980's:
. . . each design decision [should] be implemented in only one module [ --> suggested size 20 - 50 lines of code so not trivial and so focussed on one main task]. A change in any of these decisions will then require changes only to that single module. The other modules should be written so that they are totally unaware of the values chosen or the methods used in the implementing module. An important concept here is the "information-hiding principle," whereby modules share only information that is absolutely essential to getting the task done. Other information is hidden within a single module.

Error handling is a typical situation in which information should be hidden. When a module detects a lethal error, it should not try to recover; instead, it should inform the calling module of the error status and allow that module to decide how to proceed. the reason is that the lower level [called] module often lacks sufficient information to establish the recovery procedure. [Leventhal, Lance A. 6809 Assembly Language Programming (Berkley, CA: OSBORNE/McGraw-Hill, 1981) p. 17 - 64. (Yes, sectional page numbers were used. Emphases have been deleted.)]
So, already, modular and structured programming ideas were pointing the way to what would emerge across the 1990's as the dominant, objects paradigm, which is the context of Java.

Such classical program design approaches are a bit quaint today, though they give a good background for the more current approaches, which are often based on techniques associated with the Unified Modelling Language, UML. (Overview, here.) And while it would take a whole course in itself to elaborate on the UML techniques, some of the software development approaches are useful and simple enough to make their way into a "first proficiency" course like this.

Let's start with an update to the classic flowchart, the UML Activity Diagram:

Fig. F.4: A UML Activity Diagram, showing the logic of a process's step by step activities. The start and end points are now circles (end being white-ringed); activities are rounded rectangles; decision diamonds remain; and, heavy parallel bars are used to denote synchronised activities. The overall block diagram is joined in a labelled enclosure and sometimes the chart can be broken into "swim lanes" that show parallel chains of activities. However, there is an underlying logical rigour, as in UML 2.x, activity diagrams are based on Petri Nets, allowing them to capture workflows and process logic, i.e algorithms.  [Def'n: Algorithms are finite, step by step procedures that move from a start to an end state, and often solve a problem or carry out a composite task, n.b. the concept that programs code and organise algorithms to act on data in structures to effect desired solutions. In a Petri Net, in rough summary, we have nodes that can be enabled to fire once input conditions are enabled, transitioning activity initiating along the arcs to the next nodes in the chain. A mathematical modelling framework exists.]   (Source: Wiki, cf Ambler here and here.) 

Similarly, it is helpful to conceive of a software system in terms of how users of various types interact with it, using the UML use-case diagram [which can work at different levels of details up to the very broad way to interact with a system], and associated storyboards for the flow of activities for each detailed use case, e.g.:

Fig. F.5:  A system-level use-case diagram for a web based broadcast system, with use cases in ovals, packaged sets of cases in stylised folders with tabs, the system being within a box that marks its boundary, and with users being represented as stick figures. [SOURCE: Visual Paradigm, which gives more details. Ambler's discussion here is is also helpful. For those interested in modelling systems more broadly, the breakout to the system modelling perspective is helpful, cf here on SysML (explanation here, reference card here), a system modelling language linked to UML.]
Likewise, the UML Sequence Diagram, with the objects shown across the tops, "swim lanes" and indicators of how objects become active and interact on the software stage (or is this now a swimming pool?) can be helpful:

Fig. F.6: A UML Sequence Diagram, with actor/operator and objects (representing real world entities or providing clusters of background software services) interacting to carry out a task, by interacting through messages. The use case diagram allows us to study typical scenarios for the required behaviour of user - system interactions, the sequence diagram helps us see how software objects work together to do this, and the class diagram shows how the classes of objects identified are structured together, thus allowing the software network of objects to be assembled in code as a program. (It is helpful to apply the Pareto 20/80 principle -- 20% of a program's capabilities/features covers 80% of real world cases and effects, so an effective approach is to focus the core program on the pivotal 20%, and then to put in customising plug-ins to cover the odd cases; allowing for flexibility and customisation. It is often wise to allow for third parties to develop plug-in widgets that extend the function of the core program, and to share them in an exchange. [Background on Pareto here.]) The deployment diagram shows how the network of objects is put together on the ground in the actual system to be built. Other diagrams are also useful. (UML is a subject to itself, cf overview here, "cheat sheet" here, and more on seq'ce diags here. Video tutorial here.) (credit: Sanchez; pardon fuzziness.)
Objects have now "swum" into plain view (doubtless, ready to cavort around like a pod of happy dolphins), and so it helps to use the UML Class Diagram -- a Class is the blueprint for an object -- to identify the relationships among classes and objects in a program:

Fig. F.7: Classes displayed by relationships, showing in this simple example, derivation of sub-classes that extend a more generic class and also displaying many to one relationships. Each class -- a blueprint corresponding to the actual objects to be used -- shows name, state-defining variables giving attributes, and methods required for roles (which can be listed in a separate box, but it may be more effective to use CRC cards and/or ORM diagrams) [Source: Tutorialspoint. NB: OO Programming is an approach that centres on objects, and the class diagram shows abstraction and inheritance: a generic super class allows sub classes (and onward objects) to be created by inheriting the core structure, then extending it for particular specific uses. In extension, variables (so, state data) and/or methods may be added, and in some cases what was inherited can be over-ridden. Encapsulation means that data and methods are hidden to outside objects, there is only message-passing to an interface, allowing for granular modularity and reducing the tightness of coupling of modules. Polymorphism follows: by using generic messages, the particular object responds in a particular way to a given message based on its data and methods, e,g a request for colour may return green, blue or violet. ]
What remains is to see how these can be given substance by coding them in a real computer language. Thus, we turn to:

Hello World in Java

It is a bit of a tradition to begin actual programming with a simple program that generates "Hello, world!" as output.

A nice, easy beginning, that allows us to do a sanity check that things are okay with the set up in use, and also it helps us make sure we have our steps and procedures in order. So, in a webbed world, the first one we will do as a bit of a warm-up exercise is a hypertext markup language version, as this will be particularly simple and will also help us set up the contrast provided by markup languages that set up text for display.

First, call up Notepad or some similar text editor.  This might be, in: 
All Programs > Accessories > Notepad.

Open up Notepad and key in the text for the following (never mind my markups that are overlaid on it). Start with <!DOCTYPE . . .  and continue to </HTML>. Notice, we have a preliminary comment, then a head and a body, a typical structure for a web page. The actual program to be run is to display the information coded as a headline and as text.  In typing, be especially careful with the bits that are in "tags", between angle brackets [the less than and greater than signs], where also the solidus -- forward slash -- is the close-tag. Most HTML tags are paired and you have to be careful to get that right, open: <tag> . . . close </tag>:



 Save the typed in file as helloworld.html, on your desktop or a similar location, perhaps a folder you will open for this programing course. If so, label that in all lower case letters, perhaps: pgmexamples.

Fire up your favourite browser, and examine what you see when you do File >  Open > helloworld.html.  Does it look (more or less) like:



If so, congratulations, you have successfully launched your first program.

And, along the way, you have seen the first elements to building Web Pages.

Also, you will have seen some practical answers to the business of coding and running a program. For instance, the reason we used something as primitive as Notepad, is that a text editor will put out plain vanilla text without fancy markup and codes to do things like curly quote marks.

If your page will not display correctly, check to see where you made an error in transcribing. Lesson two: it is HARD to be consistently right in programming, so expect to have to look for and find then fix "bugs."

Speaking of, here is the immortalised bug (a literal bug found gumming up the works on an early computer), with an annotation in famed computer pioneer Grace Hopper's writing. Notice the time-annotated log of composing and debugging the computer in action, excellent work logging practice even today:




And, to learn more, you can try the basic HTML tutorial here. (One should know how to do a basic web page, inserting links, images, in-page anchors and the like. A bit of Cascading Style Sheets will also help. For day to day composing of pages, I suggest the freebies, KompoZer or Amaya.)

Already, it should be apparent that one has to be fairly exact in writing code, to get things to work.

Just for completeness, here -- courtesy Wiki -- is a Hello, world in the 1950's pioneering business high level language, COBOL (COmmon Business- Oriented Language, pioneered by the late Admiral "Amazing Grace" Hopper), for an IBM 360 mainframe machine c. 1972, which would have been punched on standard 80-column punch cards as numbered:
//COBUCLG  JOB CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1)
//HELOWRLD EXEC COBUCLG,PARM.COB='MAP,LIST,LET'
//COB.SYSIN DD *
  001  IDENTIFICATION DIVISION.
  002  PROGRAM-ID.  'HELLO'.
  003  ENVIRONMENT DIVISION.
  004  CONFIGURATION SECTION.
  005  SOURCE-COMPUTER.  IBM-360.
  006  OBJECT-COMPUTER.  IBM-360.
  0065 SPECIAL-NAMES.
  0066     CONSOLE IS CNSL.
  007  DATA DIVISION.
  008  WORKING-STORAGE SECTION.
  009  77  HELLO-CONST   PIC X(12) VALUE 'HELLO, WORLD'.
  075  PROCEDURE DIVISION.
  090  000-DISPLAY.
  100      DISPLAY HELLO-CONST UPON CNSL.
  110      STOP RUN.
//LKED.SYSLIB DD DSNAME=SYS1.COBLIB,DISP=SHR
//            DD DSNAME=SYS1.LINKLIB,DISP=SHR
//GO.SYSPRINT DD SYSOUT=A
//
What an 80-column punched card looked like (though, light yellow-biege was more common):


A similar, paper based technology was punched paper tape:

 


 (NB: If one is interested, there is an online accessible Fortran compiler here, and in the onward page here, it seems one may get an emulator of old IBM mainframe operating system with Fortran, COBOL etc. The fun part? Written in -- ta da! -- Java to provide a windowed environment. And in case you think COBOL is dead, the Wiki article on it remarks: "Fujitsu and Micro Focus currently support object-oriented COBOL compilers targeting the .NET framework." Likewise, the last formal definition of Fortran seems to have been issued in 2008. Fortran now looks to be able to support objects and concurrent programming. One of the capacities of Java that is of relevance here, is that it can be set up as a front end interface wrapper for back end programming in other languages. It is worth noting that BASIC has long been a family of dialects and languages, and has a major descendant, Visual Basic. The "for beginners" Small Basic is worth a mention. Likewise, we may note that Pascal has spawned a whole family of dialects and descendants. Borland's Turbo Pascal and Delphi are particularly noteworthy. But, such nostalgic notes notwithstanding, Java, C, C++, Python, Ruby etc. seem much more relevant today.)

The HTML example will stand us in good stead as we turn to doing a Java Hello World.

In steps:

1 --> While one can use a text editor such as Notepad or something a little more specialised for programming (e.g. Bluefish, JEdit, IntelliJ), let us cut to the chase scene and first download and install the latest Java SDK and the educational Integrated Development Environment (IDE) DrJava.

2 --> Having installed the software, set up a java_tutorial folder on your desktop, to make it easy to find. (You will be saving programs there.) It may help to copy a launch icon for DrJava into the same folder using Right-click, and hold - drag and release, accepting "Make a shortcut here."

3 --> Launch Dr Java. It should look something like:


4 --> Key in the following Hello World Program, then save it as HelloWorld1.java. Open the Tools menu, then click compile current document. If errors show up, correct what you have typed (it should be highlighted in Yellow). When it compiles and the run document option is ready (not greyed out) run the program. The output should be as follows, more or less:


5 --> Congratulations, you have typed in, compiled (probably debugged) and run your first Java program. Now, let us take a closer look so we can begin to understand it, as a first case study of Java programming:


6 --> At first pass level we can see certain key words and layouts as "magic incantations" that are required to please the compiler, for the program to work. That is where we have been so far.

7 --> At the next level, we need to try to see what is going on at first level. The easiest to see is that lines 1 - 4, 6 & 8 are comments, ignored by the compiler but helpful in guiding the reader of the program. Lines 1 - 4 are a multi-line comment, which Java requires to be set up between /* and */.  Lines 6 and 8 are single line comments, introduced by a double solidus: //. (There is a third type of comment in Java, that allows for pulling out certain documentation remarks for official documentation, automatically. It lives between /** and */. A great place to use it it in the headline for a program.)

8 --> Line 5 defines a class (the blueprint for an object created when a program runs), the basic "capsule" used in Java. Here that is the actual source program, contents between the double-brackets or curly braces in lines 5 and 11. The name of the class, of course, is HelloWorld, and the class should be saved under the identical name, with a dot java extension:  HelloWorld.java. By declaring the class public, when it is instantiated, other objects may access it. (Lastly, if one is rolling one's own with a text editor, one would compile from console: javac HelloWorld.java. This will create a class file with the bytecodes for the program, HelloWorld.class. Bytecodes are of course the code that feeds the Java Virtual Machine, JVM, which executes the program on the system.) It is worth taking a look at a block diagram of the JVM:

Fig. F.8: The Java Virtual machine, JVM. By creating a standard virtual computer that runs byte codes, in theory any Java program can run on any computer. The messy details of interfacing to the hardware are left to the expert programmers who build the JVM for a particular machine, a phone, or a robot vehicle roaming Mars, or a desktop PC, etc.The JVM takes in byte codes, and reads them then processes them one by one or using a speed up technique called a just in time compiler -- Java earned an early reputation for being slow, in large part due to being interpreted line by line when it ran, so it had to be speeded up -- with a memory management facility for "garbage collection." This makes sure memory does not get eaten up with information no longer needed by the program. In real time implementations of Java (used to control things that require fast response), this has to be in part disabled. WORA, write once run anywhere, of course, remains a theoretical ideal, as usual.


9 --> Line 7 of the program gives us the main method, which is where any Java program begins actual execution, it is the main "subroutine" to be carried out and will call on others as needed. Public -- again accessible from outside the class where it is created, static, the method is accessible before actually instantiating an object of the class. Void, it does not return a result value to the calling object. String args [] within the bracket of main, says the program uses strings of characters as the variables or parameters it works on, the arguments. Of course, all of these are laced with subtleties that will be evident as one practices coding, but this is enough for a first rough idea. Again, curly braces between lines 7 and 10 give the range of main.

10 --> The actual work of HelloWorld is done in line 9, which calls a utility, System.out and dots again to point to a method, println, which prints a line and then does a return. In effect, System is a class that allows access to the system in use, and out allows output stream connected to the console that will put the output to this particular output facility.

11 --> The actual print line method is then called to push the block inside it to the output on the console. As can be seen in the screen shot above. The line to be printed is in the brackets, between straight quote marks. Unsurprisingly, "Hello, World!"

12 --> All else is built up from or extends this.
xxx

Sequencing and Branching

xxx
The next step is to look at how Java implements two main programming structures, sequences and conditional branches:

13 --> To see a simple sequence, open the HelloWorld program in Dr Java and then save it as HelloWorld2, renaming the class in the code. Adjust the program as follows:


14 --> Compile, clean up as necessary, and run. We should have the output as seen.

15 --> Notice, we now have a sequence of three actions in main, two System.out.print steps and a System.out.println. You will see that the first step prints "Hello, world" just as is in the quotes. The second chains "1 + " right after it, with spaces before and after the plus sign. The third, chains a 2 and then closes the line with a hard return. (Notice the difference between print and println.)

16 --> The next program, HelloWorld3, will show conditional branching, in the context of identifying whether or not a given amount of fuel in US Gallons will over-fill a tank with capacity specified in litres. Type it in as follows:

/******************************************************************
  * Our third educational program case will print the message "Hello,
  * world!"  to the console on the screen then will demonstrate
  * decision making and branching with a unit conversion from g U.S.
  * gallons to l litres, tested for capacity c of a given tank in litres.
 * On testing, the program will print an appropriate message,
 * using the if ____ else _____ structure. The next case will
 * introduce the third main structure, looping, to automatically
 * identify the capacity in gallons of a fuel tank of a given size,
 * c litres. (Of course this is using a sledgehammer to crack a nut,
 * and will win no awards for elegant, compact professional style;
 * but it is useful for our current educational purposes.)
 * *******************************************************************
 */
public class HelloWorld3{
  // The main method is the entry of the program
  public static void main(String args []){
   
      // next we print the greeting message to the console output
      System.out.println("Hello, world!");
   
    //declaring variables, type floating point
    double g; // number of gallons, double precision floating point
    double l; // number of litres, double
    float c;// capacity in litres, single precision floating point
    double e;// excess of fuel over capacity
   
    //giving values
    g = 11.8;// input quantity of gas in US gallons
    c = 45;// input fuel tank capacity in litres
   
    //declaring the relationships
    l = g * 3.78541; // converting U.S. gallons to litres
    e = l - c;// finding out if there is or is not an excess
   
    //this is followed by the conversion and -- if required -- a warning
    System.out.print(g + " U.S. gallons");
    System.out.println(" is the same as " + l + " litres");
    if(e > 0) System.out.println("WARNING: fuel tank capacity is exceeded!");
    else System.out.println("Fuel tank capacity is not exceeded.");
                        
  }
}
17 --> I'll bet you were lazy and copy-pasted. Well, it is actually important to practice typing then finding and fixing bugs, so do please do so.  (Now you know why the first three coding examples were given as image files!)

18 --> This program introduces some new things as well. First, the introductory comment is much more extensive, explaining what is going on in a nutshell. It is an abstract. The familiar hello world message is done up front, to help us keep track.

19 --> Some variables are declared as type floating point (can take a partly or completely fractional value not just a whole number), some double precision: double, one single precision: float. Notice, the program then assigns values right from when we type it in. (Later we will look at keyboard inputs, which brings up some further complexities.)

20 --> In sequence, some relationships are defined that allow conversion of US gallons to litres and comparison to see if there is an excess of fuel over capacity. This last allows introduction of the conditional branching, through allowing a test of the condition.

21 --> Outputs are then printed to console, First a message that g US gallons is l litres. This is a sequence.

22 --> After this, we have an IF/ELSE conditional branch, written in Java style. One or the other of the two messages, the warning or the statement that capacity is not exceeded, will be printed.

23 --> Save, compile and run, then play around by varying g and  c. What happens? Why?

24 --> Set back the initial values of g = 11.8 and c = 45, then change  g to a negative value (put - and space before the 11.8) and save, compile and run the program. Next, change c to - 45, and run again with both g and c negative. What is happening, why? Is this a bug or is it unreasonable to expect users to put in a negative numerical value for g or c unless told to do so? Why or why not?

xxx



Looping

Quite often, programs need to do something over and over while or until a condition holds. So, looping extends branching by allowing the program to go back over a set of instructions again and again until a test condition releases the program. (There is a further extension where some loops need to be "do forever" or more realistically until an interrupt or power down stops execution.)

In this case, we do an example that calculates the volume of gas in US gallons that fits into a tank specified in litres as typed in based on a prompt:

/* ********************************************************
 * Our (adjusted) fourth educational program case will print "Hello, world!"
 * to the console on the screen then will demonstrate automated decision
 * making, via looping and branching to estimate the capacity c of a tank
 * in U.S. gallons, through iterative loops. In this version, the keyboard
 * will be used to enter the capcity, c. On identifying the capacity
 * to the nearest 1/100 gallon, the program will print an appropriate
 * message. (Of course this is using a sledgehammer to crack a nut,
 * and will win no awards for elegant, compact  professional style;
 * but it is useful for our current educational purposes.)
 * **********************************************************
 */

// First, we import the Java built in utility that allows keyboard scanning

import java.util.Scanner;

public class HelloWorld4b{
 
  // The main method is the entry of the program for execution
 
  public static void main(String args []){
  
    //declaring variables, types floating point and integer
  
    double g; // number of gallons, double precision floating point
    double l; // equivalent number of litres, double
    float c;  // capacity in litres, single precision floating point
    int i;    // first loop iteration counter for the 1 gallon steps
    int j;    // second loop counter for the 1/10 gallon steps
    int k;    // third loop counter for the 1/100 gallon steps
  
    //giving an initial value of g and a default escape value for c
  
    g = 0;// initial quantity of gas in US gallons
    c = 0;
    l = 0;
  
      // Next we print the greeting message to the console output
 
    System.out.println("Hello, world!");
  
    // taking input of c as a floating point, single precision value
  
     try {
  
    Scanner in = new Scanner(System.in);//scans input value of c from keyboard
  
    System.out.println("Enter a 'reasonable' NUMERICAL value of tank capacity, c, ");
    System.out.println("in litres and press the 'Enter' key:"); // setting up . . .
  
   // now, takes in the input now (a given number of litres), and confirms it . . .
      c = in.nextFloat();
      System.out.println("You entered tank readable capacity " + c + " litres.");
     }
      catch(Exception exception) {
  //Error message warning that the output is a default (and is correct for that!)
        System.out.println("Not a correct TYPE of value for TANK CAPACITY.");
        System.out.println("The current value of c after the error, is " + c);
        System.out.println("The value in gallons resulting below is a DEFAULT!");
    }

    //iteration on the volume to the nearest higher whole number of gallons
      //while loop approach
    i = 0; //first loop counter
    while (l < c){
      g = g + 1.0; // increase g in 1 gallon steps until it is such that l >= c
    
      // the strange use of an equals sign is to assign a value to g,
      // g being in effect a memory location container (actually, it points to it)
      // We can see this as: g_orig + 1.0 --> g_next,
      // g_next immediately being used to get l_next:
    
      l = g * 3.78541; // converting U.S. gallons to litres
      i++; // this means, increment i by 1 i.e.  i + 1 --> i
    } ;// the while condition for the do while loop, goes back to do
  
    //We now know the number of gallons that is one too much, so back off 1
  
    g = g - 1.0; //subtract one gallon and feed the result back into g
  
    //now for the 1/10 gallon loop
  
    j = 0;//second loop counter
  
    //set up loop 2 to increment in 1/10 gallon steps
    do{
      g = g + 0.1;
      l = g * 3.78541; // converting U.S. gallons to litres
      j++;
    } while (l < c);
  
    //number of gallons is 1/10 too high,
  
    //so take off one and loop for 1/00 gal steps
  
    g = g - 0.1;
    k = 0; // 3rd loop counter
    do{
      g = g + 0.01;
      l = g * 3.78541; // converting U.S. gallons to litres
      k++;
    } while (l < c);
  
    g = g - 0.01; //we are now 0.01 gallon high so shave this away.
  
    // Now, print the results
  
    System.out.println("The first loop took " + i + " iterations.");
    System.out.println("The second loop took " + j + " iterations.");
    System.out.println("The third loop took " + k + " iterations.");
    System.out.println("Tank capacity is (or is just over) " + g + " U.S. gallons");
                       
  }
}
25 --> Enter the program, save, compile and run. Feed in a tank capacity 58 litres. What happens? Try 19 l, 1750 l, and then - 45 l. Yes a negative value.

26 --> What happens, why?

27 --> Go back and look at the part of the code that runs:
try {
  
    Scanner in = new Scanner(System.in);//scans input value of c from keyboard
  
    System.out.println("Enter a 'reasonable' NUMERICAL value of tank capacity, c, ");
    System.out.println("in litres and press the 'Enter' key:"); // setting up . . .
  
   // now, takes in the input now (a given number of litres), and confirms it . . .
      c = in.nextFloat();
      System.out.println("You entered tank readable capacity " + c + " litres.");
     }
      catch(Exception exception) {
  //Error message warning that the output is a default (and is correct for that!)
        System.out.println("Not a correct TYPE of value for TANK CAPACITY.");
        System.out.println("The current value of c after the error, is " + c);
        System.out.println("The value in gallons resulting below is a DEFAULT!");

    }
28 --> Notice, how Scanner takes in keyboard data in the console pane, but has to account for exceptions. That is the job for try-catch exception handling. What do you think it is doing, why?

29 --> Now, the first loop:

//iteration on the volume to the nearest higher whole number of gallons
      //while loop approach
    i = 0; //first loop counter
    while (l < c){
      g = g + 1.0; // increase g in 1 gallon steps until it is such that l >= c
    
      // the strange use of an equals sign is to assign a value to g,
      // g being in effect a memory location container (actually, it points to it)
      // We can see this as: g_orig + 1.0 --> g_next,
      // g_next immediately being used to get l_next:
    
      l = g * 3.78541; // converting U.S. gallons to litres
      i++; // this means, increment i by 1 i.e.  i + 1 --> i
    } ;// the while condition for the do while loop, goes back to do
  
    //We now know the number of gallons that is one too much, so back off 1
  
    g = g - 1.0; //subtract one gallon and feed the result back into g

29 --> Notice, now, no less than THREE loops, counted with i, j, k. What is the effect of forcing the loop to be done at least once, on getting a correct value for the capacity? Observe, how the condition to be tested is stated.

30 --> Also, observe the use of the double-brackets to give the range of blocks of code embraced by the try-catch and the loop. What would happen if these were misplaced or omitted?

31 --> Run the program again, but this time key in abcdef as the volume. What happens, why?

32 --> Now run it again, keying in 45 + 45*i, which is something mathematicians call a complex number. (Where i is the imaginary number, the square root of - 1.) You should see the same result as for keying in 45 litres. That happens because Java does not have complex numbers as a basic, built-in type. Certain science/math oriented languages such as Fortran and Algol do. You would have to add a mathematics package to Java to handle such, like the Apache Common Math library. (See discussion here. This is not a simple topic, it is just included for completeness. Not advisable to try at this stage.)

xxxxxxx


AWT and windowing, objects


Some AWT components (HT: Wiki)
There are three fairly common windowing environments for Java coding: Abstract Window Toolkit (AWT), Swing, and Standard Widget Toolkit (SWT). AWT puts a Java "sweetie wrapper" on the native system's tools for windowing, which means objects such as buttons etc can look radically different on different operating systems.  For the same program. Not nice. Uniformity being desirable, SWING therefore builds on AWT to create a "consistent" look and feel for Java windows. At least, that's the aspiration.

SWT is a sort of compromise between the two earlier approaches and is specific to the Eclipse integrated software development environment (IDE), which is a professional level cousin to the now familiar Dr Java IDE. Eclipse was originally developed by IBM, but is now maintained by its own Foundation. But, because of this specificity to Eclipse, we obviously need not go any further with SWT in an introductory unit.

So, we won't -- but you will at least know what is meant if it comes up.

Swing (as noted already) is partly based on AWT, and is more complex though more flexible and feature-rich. That makes Swing a "build-on" topic, not a foundational one. We also set Swing to one side, for the moment.

So, AWT -- though a bit old fashioned  -- is a reasonable point to begin a first, very basic look at the business of coding with windows and such familiar windowing elements as labels, buttons, check boxes, text fields and areas, etc.

For example, we can consider a software calculator as a typical practical case of the sort of windowed interactive environment using the basic elements as identified.  One, that shows how interactive the software is and implies that designing the interface through the software window is now a major aspect of the programming process.

Let's look at our cast of actors on the stage viewed through the window:

An example, a software window based calculator. (NB: XCalc is a free RPN
calculator used for illustrative purposes only, it may or may not be actually coded in Java)


Of course, our underlying programming framework is  "MVC-DCI, implementing software objects on a stage viewed and manipulated through a window."

What AWT does, is to implement a "lowest common denominator" set of windowing elements common to major operating system environments. Which it has to, if it is to be write once, run anywhere --WORA. It does so by coupling to the standard way such elements are presented in the various operating environments.

In short, as already mentioned, it puts a Java "sweetie wrapper" around the native "peer" graphical user interface process.

Again, that means the look ["view"!] and feel ["controls"!] for AWT based windowing will vary with the operating system environment. (Swing, by contrast, uses core AWT elements then builds on a more uniform and extensive environment, by using Java code to implement a more uniform look-feel, though it may be a bit disjoint from the "standard" local environment.)

AWT is meant to work with Applets (effectively, typically "small" Java programs hosted in browser windows), and it will also work with standalone Java programs. FYI, when Java was first released, it was thought that Applets were going to rule the web. They haven't -- and they took part of the rap for Java's early reputation for slowness, but Java (and so also AWT -- a part of Java's set of Foundation Classes built into all Java environments) will also work with standalone applications (as we have been using so far).

AWT uses a hierarchy of very familiar sounding objects, starting from a core element, Component (temp image):


Thanks to the wayback machine -- yes, some of this is that old -- we can cite jGuru on how all of this works:

All [AWT] graphical user interface objects stem from a common superclass, Component. To create a Graphical User Interface (GUI), you add components to a Container object. Because a Container is also a Component, containers may be nested arbitrarily. Most often, you will use a Panel when creating nested GUIs.

Each AWT component uses native code to display itself on your screen. When you run a Java application under Microsoft Windows, buttons are really Microsoft Windows buttons. When you run the same application on a Macintosh, buttons are really Macintosh buttons. When you run on a UNIX machine that uses Motif, buttons are really Motif buttons . . . .

An Applet is a Panel that is automatically inserted into a web page. The browser displaying the web page instantiates and adds the Applet to the proper part of the web page. The browser tells the Applet when to create its GUI (by calling the init() method of Applet) and when to start() and stop() any special processing.

[Standalone] Applications [--> as we have used so far] run from a command prompt. When you execute an application from the command prompt, the interpreter starts by calling the application's main() method [--> which then calls others, as we have seen].

[--> NB: FAQs are here, courtesy the Wayback machine.]

Similarly:

There are three steps you take to create any [AWT] GUI application or applet:
  1. Compose your GUI by adding components to Container objects.
  2. Setup event handlers to ["listen" for and] respond to user interaction with the GUI.
  3. Display the GUI (automatically done for applets, you must explicitly do this for applications).
Notice, too, how user-level view- and- control interaction with the underlying software objects [the models in the MVC framework] happens:

When you display an AWT GUI, the [Java] interpreter starts a new thread to watch for user interaction with the GUI. This new thread sits and waits until a user presses a key, clicks or moves the mouse, or any other system-level event that affects the GUI. When it receives such an event, it calls one of the event handlers you set up for the GUI. Note that the event handler code is executed within the thread that watches the GUI!  . . . . 

Because this extra thread exists, your main method can simply end after it displays the GUI. This makes GUI code very simple to write in AWT. Compose the GUI, setup event handlers, then display.
As a first, toy example let us look at a window that sets up buttons that change the colour of a window:

/********************************************
* This first AWT demo example creates buttons that change the window colour
* (Not to be taken as an example of wonderful programming technique.)
* Thanks to the online original.
********************************************
*/

// Import PACKAGES of classes to carry out AWT tasks
import java.awt.*;
import java.awt.event.*;

// Note how frame is extended, and the pgm listens for, responds to events
public class ButtonDemo1 extends Frame implements ActionListener
{
  // Buttons defined in a flow layout, L to R one after the other
  Button redBut, greenBut, blueBut, closeBut;
  public ButtonDemo1()
  {
    setLayout(new FlowLayout());

    //buttons and actions defined
    redBut = new Button("RED");
    greenBut = new Button("GREEN");
    blueBut = new Button("BLUE");
    closeBut = new Button("CLOSE");

    redBut.addActionListener(this);
    greenBut.addActionListener(this);
    blueBut.addActionListener(this);
    closeBut.addActionListener(this);

    closeBut.setForeground(Color.red);

    add(redBut);
    add(greenBut);
    add(blueBut);
    add(closeBut);
   
 // Title bar title and size of windowin pixels, set to be visible
    setTitle("Buttons in Action");
    setSize(300, 300);
    setVisible(true);
  }

  //actions in case of events of pressing buttons
  public void actionPerformed(ActionEvent e)
  {
    String str = e.getActionCommand();

//notice, ladder of if-then-else steps, i.e. a case structure

    if(str.equals("RED"))
      setBackground(Color.red);
    else if(str.equals("GREEN"))
      setBackground(Color.green);
    else if(str.equals("BLUE"))
      setBackground(Color.blue);
    else if(str.equals("CLOSE"))
      System.exit(0);
   }
// minimal main . . . implement an object that implements button demo  
  public static void main(String args[])
  {
    new ButtonDemo1();
  }
}

1 -->This exercise calls up canned packages that implement AWT, from Java's library of classes. (A package, in a nutshell, is a grouped cluster of classes capable of implementing functional objects.)

2 --> If you key it in, compile it and run it, you should see the following, top left the screen on top of Dr Java:


3 --> Notice the set title in the title bar, and the close box to the right [which will not close, you must click the CLOSE button!].

4 --> Also, notice the buttons. Click in order, to see the background go bright red, green and blue. On clicking the CLOSE button, the window will close and a message will appear. Close it.

5 --> Obviously, this is a toy (and a hint about how much behind the scenes programming work goes into even "simple"  familiar window interfaces . . . ), but it shows:
  •  software windows, 
  • titles, 
  • pre-set elements for windows, window sizing
  • buttons as objects, 
  • layouts for objects in a software window,
  • action listeners, 
  • event-handlers,
  • visibility,
  • model-view-control,
  • events due to the user actions, 
  • responses due to control inputs from the user, 
  • the use of main to call the actual working code object into action and get out of the way, and 
  • termination under user control.
6 --> More sophisticated cases build on this, but already we can see that details count and we have to correctly specify each required aspect for the code to work.

vvvvvvvv

For Discussion


xxxxxx



Assignments

xxxx


XXXX