Learn Java with Licorice

Learn the basics of Java programming by immersing yourself in the world inhabited by

Licorice the cat and the other beasts at the Bestiary. With this Java tutorial, you will literally be studying the language with the help of Java natives. They will react to your efforts, and will tell you when you've made a mistake.

To visit and awaken the Bestiary world and its Java language school:

To clarify the above, if the example Java code on a tutorial page is:
System.out.println("Let's get started");
then the actual text in the console will be:
<script implName="lang:beanshell:inline:"><![CDATA[
System.out.println("Let's get started");
null;]]></script>

The plan is to have Licorice lead you through the following paw prints.

  1. Displaying information
  2. Assigning values
  3. For loops
  4. Methods
  5. While loops
  6. Recursion
  7. If ... Else ...
  8. Switch

Displaying information

Ken Webb Sun, 01 Aug 2010 22:42:23 +0000

A good place to start with Java programming is learning how to display information. Try these examples by typing them into the Bestiary console panel. Or you can just copy and paste, or drag and drop, them into the console. Then press the Submit button on the same page. To see the results, you will need to have the Java console enabled.

System.out.println is the standard Java method for displaying information to a user. In the first set of examples below, Java prints a string of text, adds and prints two integers, and then adds and prints two floating point numbers.

System.out.println("Hello Licorice!");

System.out.println(123 + 321);

System.out.println(123.0 + 321.456);

contextNodeKey is a Java attribute that already exists within the Bestiary environment. It's the currently selected node in the app.

System.out.println(contextNodeKey);

Programming in any computer language, including Java, is error-prone. There is no attribute called error. Look in the Java Console for more details about the error after you Submit the following example. You will need to use the Pause button to freeze the app while you examine the error message.

System.out.println(error);

Assigning values

Ken Webb Mon, 02 Aug 2010 02:42:05 +0000

Computer programs are full of attributes (also called variables) that contain values. An attribute is just something with a name that stores text, a number, or some other value. The following example includes three attributes.

int x = 2000;
int y = 10;
int z = x + y;
System.out.println("The answer is: " + z);

In the next example, the Bestiary internal attribute contextNodeKey is rather long, so it can be useful to create a separate internal attribute that's shorter. In Java, the type of information must be specified for each attribute. cnode is an IXholon type. The import statement at the top is required to tell the system where the IXholon class (type) is located.

import org.primordion.xholon.base.IXholon;
IXholon cnode = contextNodeKey;
System.out.println("The current context node is: " + cnode);

While loops

Ken Webb Mon, 02 Aug 2010 03:01:21 +0000

Each row in the original version of the Bestiary has 100 habitat cells. Change the current context node to a row, for example to row 1.

xpath /descendant::Row

The following script should confirm that the row has 100 child nodes.

import org.primordion.xholon.base.IXholon;
IXholon contextNode = contextNodeKey;
int sum = 0;
public void count(IXholon node) {
 node = node.getFirstChild();
 while (node != null) {
   sum++;
   node = node.getNextSibling();
 }
}
count(contextNode);
System.out.println("Node " + contextNode + " has " + sum + " child nodes.");

For loops

Ken Webb Mon, 02 Aug 2010 12:32:31 +0000

A for loop is a very common programming statement. In the following example, the variable i is iterated from a value of 1 to 10. System.out.print displays each of these values. This is how you get your computer to count from 1 to 10.

for (int i = 1; i < 11; i++) {
 System.out.print(i + " ");}
System.out.println();

Especially in the summer, Licorice hates to come back into the house. Sometimes I can coax him by holding a tasty treat under his nose. To try this, first you'll have to catch him. Enter the following in the console, to make Licorice (cat 2) the current context node:

xpath /descendant-or-self::*[@name='cat_2']

If the current context node is a cat, human, or other beast, then the following script will boost him or her a specific distance in a specified direction. Set myDistance to some value between 1 and 100, and myDirection to one of the eight choices. Note the use of the for loop to advance the destination by the desired distance.

import org.primordion.xholon.base.AbstractGrid;
import org.primordion.xholon.base.IGrid;
import org.primordion.xholon.base.IXholon;
IXholon myBeast = contextNodeKey;
int myDistance = 5;
// choices: P_NORTH P_NORTHEAST P_EAST P_SOUTHEAST P_SOUTH P_SOUTHWEST P_WEST P_NORTHWEST
int myDirection = IGrid.P_NORTH;
public void boost(IXholon beast, int distance, int direction) {
 AbstractGrid destination = (AbstractGrid)beast.getParentNode();
 for (int i = 0; i < distance; i++) {
   destination = (AbstractGrid)destination.port[direction];
 }
 beast.removeChild();
 beast.appendChild(destination);
}
boost(myBeast, myDistance, myDirection);

Recursion

Ken Webb Mon, 02 Aug 2010 12:33:12 +0000

Licorice and company live in a hierarchically structured world, much like the universe that you and I inhabit. There are things inside of things, that in turn are inside of other things, and so on. Java can easily navigate this type of structured world, by using recursion.

If you haven't made any changes to the Bestiary, and if the current context node is Bestiary/Grid, then the following script should report that there are 10591 nodes:

Node Type Number of Instances
Grid 1
Row (100 rows in the grid) 100
HabitatCell (100 cells per row) 10000
Cat 100
Cat behaviors (3 behaviors per cat) 300
Human 30
Human behaviors (2 behaviors per human) 60
import org.primordion.xholon.base.IXholon;
IXholon contextNode = contextNodeKey;
int sum = 0;
public void count(IXholon node) {
 sum++;
 node = node.getFirstChild();
 while (node != null) {
   count(node);
   node = node.getNextSibling();
 }
}
count(contextNode);
System.out.println("There are " + sum
 + " nodes in the subtree rooted by " + contextNode + ".");

Methods

Ken Webb Mon, 02 Aug 2010 12:34:02 +0000

A method is a named piece of code that does something specific. Ideally, it should only do one thing, and its name should strongly suggest what that thing is. A method may accept parameters, and it may return a value. In the following simple example, the method name is add, the input parameters are 17 and 25, and an int result is returned and printed. Try various values, both positive and negative integers.

public int add(int a, int b) {
 return a + b;
}
System.out.println(add(17, 25));

Licorice loves methods. He's got a method to avoid being found, methods to demand food, and any number of other methods designed to reinforce my role as servant. The following example has three methods, one of which will be randomly called each time the script is run.

public void feedMeNow() {System.out.println("MEOW (FEED ME NOW!)");}
public void pleaseFeedMe() {System.out.println("miew (please feed me)");}
public void imSoHungry() {System.out.println("meouch (I'm so hungry)");}
double rnum = Math.random();
if (rnum < 0.25) {feedMeNow();}
else if (rnum < 0.5) {imSoHungry();}
else {pleaseFeedMe();}

If ... Else ...

Ken Webb Mon, 02 Aug 2010 12:34:40 +0000

Conditional logic is an essential part of any software. The if statement makes a decision based on current conditions, and follows the path dictated by the decision.

double rnum = Math.random();
if (rnum < 0.5) {
 System.out.println("Heads I win.");
}
else {
 System.out.println("Tails you lose.");
}

In the section on while loops Licorice was boosted toward a destination. But if you specify an invalid value for myDistance or myDirection, the program could crash or could go into an infinite loop, which could lock up your applet or application. It's good practice to always verify human input. The if statement is typically used to do this. The following is an updated version of the boost method, with validation. Try it out.

import org.primordion.xholon.base.AbstractGrid;
import org.primordion.xholon.base.IGrid;
import org.primordion.xholon.base.IXholon;

IXholon myBeast = contextNodeKey; int myDistance = 5; // choices: P_NORTH P_NORTHEAST P_EAST P_SOUTHEAST P_SOUTH P_SOUTHWEST P_WEST P_NORTHWEST int myDirection = IGrid.P_NORTH; public boolean isOk(IXholon beast, int distance, int direction) { boolean ok; if (beast == null) {ok = false;} else if ((distance <= 0) || (distance > 100)) {ok = false;} else if ((direction < 0) || (direction > 7)) {ok = false;} else {ok = true;} return ok; } public void boost(IXholon beast, int distance, int direction) { AbstractGrid destination = (AbstractGrid)beast.getParentNode(); for (int i = 0; i < distance; i++) { destination = (AbstractGrid)destination.port[direction]; } beast.removeChild(); beast.appendChild(destination); } if (isOk(myBeast, myDistance, myDirection)) { boost(myBeast, myDistance, myDirection); }

Switch

Ken Webb Mon, 02 Aug 2010 12:35:08 +0000

The switch statement is an efficient way to handle a decision that has more than 2 choices, but only if the conditions involve integer values.

int choice = 17;
String desert;
switch (choice) {
case 1: desert = "ice cream"; break;
case 17: desert = "chocolate cake"; break;
case 1776: desert = "apple pie"; break;
default: desert = "stale bread"; break;
}
System.out.println("We're having " + desert + " for desert!");

Licorice doesn't like any of these deserts, so we'll have to find something else for him to do.

// TODO

Swing

Ken Webb Thu, 09 Sep 2010 22:45:29 +0000

Swing is the name of the default graphics/GUI library included with Java. This is a simple example of a Swing GUI that can be pasted into the Bestiary or other Xholon app. You can try any number of variations of this code, until you arrive at the content and look that you want.

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;

JFrame frame = new JFrame("Hello Licorice");
JPanel panel = new JPanel();
JLabel label = new JLabel("Buenos Dias Regaliz");
JButton button = new JButton("Bonjour Réglisse");
panel.add(label);
panel.add(button);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);

return to main page