First time here? Please, start at the beginning.

Thursday, November 4

Reflection....

As I often do, I set my goals quite high for this project. And, as usual, lost interest long before those goals are even well-defined, much less near at hand.

My own growing disinterest, preoccupation with other things (such as school work), and a seeming lack of interest from any readers has led me to largely forget about this project.

BUT THERE MAY BE HOPE!

My school semester is nearing its end, so I may be able to resume this project; however, I won't do it alone:

IF ANYONE OUT THERE STILL CARES ABOUT THIS, COMMENT AND LET ME KNOW!!
OTHERWISE THIS WILL DIE!!

As of this writing, not a single comment has been posted on and article of this blog. And that's rather disheartening.

In retrospect, this idea may have been better implemented as a discussion forum... Maybe I'll set one up if some interest is shown.

Thursday, September 16

Rewind: back to syntax

I've decided to back up a bit, away from uChat, and talk more about syntax. Some of this is near universal to all programming languages, some is more Java-specific.

Statements and expressions
Put simply, a statement is any executable line of code in your program. Several languages (Java, C et. al.) require a semicolon at the end of each statement, others don't (optional in perl).

Before I delve too deeply, a couple more terms. A "token" is the compiler's equivalent of a word; it generally has no meaning by itself. Keywords, operators, and identifiers are all tokens, as are braces and other punctuation-like symbols. An "identifier" is a name, it can be the name of a variable, a method, a class, or even a package.

A statement is generally built from expressions. An expression is a token or string of tokens that evaluate to a value. Time for an example:

(Assume that x is an int variable.)
5;     // expression: integer literal (also, by itself, a compiler error)
x = 5; // statement: puts the value on the right (5) in the variable on the left
3 + 2; // expression: integer literal, evaluates to five (also a compiler error)
x = 3 + 2; // statement

A method call is also an expression: is evaluates to the return value of the method. For example, the Integer.parseInt() method accepts a String and returns an int.

Tuesday, September 7

uChat as an FSM

No, not a Flying Spaghetti Monster, a Finite State Machine.

Wikipedia's article is rather long and dry. To put it briefly, a finite state machine is a device (or program) that has a set number of "states". An example would be a light switch: it has 2 states, "on" and "off". A dimmer switch, to contrast, would be an Infinite State Machine: it has a (nearly) infinite number of positions.

It addition to its set of states, a state machine also has "transition conditions" that cause it to change its state and (usually) a set of reactions that change depending on its state.

Here's another example, you could model a body of water as an FSM. It's states would be "solid", "liquid" and "gas". Its transition conditions would be defined as temperature changes, and its reactions would change depending on its state. If you poke a piece of ice sitting on a table, it will likely slide away; however, if you poke the surface of a pool of water, it will ripple. A slightly odd example, but I believe it serves its purpose.

Virtually every computer program you interact with is a Finite State Machine. Some have obvious states, others are more subtle, but few complex programs can be written without maintaining an internal state and altering its reactions to user input accordingly.

"But," you ask, "how is a simple program like uChat a Finite State Machine?" It may not be obvious from a glance at the source, but it is. A simple one, granted, with only 2 states: "connected" and "disconnected".

Fun fact: this picture's filesize is larger than uChat's source.

Lets list uChat's input sources, they're all part of the UI: the Name field, the Join button, the Message field, and the Send button.

The text area is marked an non-editable, so no user input can come from it. Also, clicking the Send button has the same effect as pressing enter in the Message field. There's a similar relation exists between the Name field and the Join button.

So, simplified slightly to "user intents" (actions the user intends to perform) we now have: "join the chat" (connect), "leave the chat" (disconnect), and "send a message".

The program's possible responses are: join the chat, leave the chat, send a message, ignore.

This post is incomplete. I may or may not return to this subject later, but I believe I've explained sufficiently for you to understand where I was going.

Wednesday, August 25

uChat: Network Protocol

(I think I'm going to abandon the "Part X.Y" thing, for now at least.)

As mentioned once before, uChat uses UDP broadcast packets to communicate. This isn't exactly ideal: every computer on the network can "listen in" if they listen on the right port. But it's an easy way to communicate without the need for a central server.

How do you send a UDP broadcast? It's dead-simple: just set the destination IP address of your packets to 255.255.255.255, the broadcast address. These packets will be discarded by a router, so we're not clogging up the entire Internet, just the local LAN.

By the way, the port number used is 12121. Just a randomly chosen number above 1024 (Unix-like systems generally require root access to use ports below 1024). Any port would do really, as long as everyone you want to talk to uses the same one.

Now, just what do these packets say? The content of each packet is a 4 character code followed by the message. The current version uses only 4 message types, but more could be added without trouble as the program discards a packet that it doesn't understand.

Here's the message types and their meanings:
  • "SAY:": this one should be self explanatory, the message is what the sender of the packet "said"
  • "JOIN": sent when someone clicks the "join" button, it announces that someone has joined the chat, the message is the name/alias entered in the upper text area
  • "LEAV": reverse of "JOIN", message is also the name/alias
  • "HERE": sent as a response to a "JOIN" packet, it informs the joinee of who is already present, the message is, again, the sender's name/alias

Why so many devoted to keeping track of who's present? Because the "SAY:" packet doesn't include the name of the sender, only the IP address. Each instance of uChat is responsible for maintaining an IP-address-to-name mapping table (the lookupTable variable).

That's really it. Simple, eh? You can watch it in action with a program like WireShark (I've never tried that myself, but there's no reason it wouldn't work), or by running netcat on another machine with: "nc -lup 12121".

Monday, August 23

Layout...

To get some extra width for code samples, I've moved the archive list to the bottom. To compensate for that, I've adjusted it to 2 posts per page. I'm not really fond of how it looks now and may end up changing it back.

Also, comments no longer require login.

Part 2.1: uChat Source explained (mostly)

Here's the (mostly) annotated and explained source for uChat. The really rough parts are left out for now, they'll get their own posts a bit later.

I can't stress enough the importance of copy-pasting this into your editor of choice, the word wrap is going to make this impossible to dechpher. I'll see what I can do about the site layout.

//lots of imports here
import java.util.*; // name-IP address map
import java.net.*;  // several Socket classes and InetAddress
import java.io.*;   // IOException and a couple *Writers

import java.awt.*;       // GUI elements
import java.awt.event.*; // GUI event handlers

import java.util.regex.*; // regular expression library, used to prevent a minor exploit

// changed the class/file name, class names should usually start with a capital
// subclass java.awt.Frame (a window) so we can be displayed on-screen
// implement WindowListener and ActionListener (from java.awt.event) so we can handle our own events
// implement java.lang.Runnable so we can listen for incoming messages in a seperate thread
// (I've reciently realized multi-threading wasn't actually necessary...)
public class uChat extends Frame implements WindowListener, ActionListener, Runnable {

// NOTE: within source code, I tend to use "us", "we", "our", etc. to refer to the class/program and it's actions. Don't ask why, I don't know.

 // network-related vars
 InetAddress addrs;   // broadcast IP address, declared below
 int port = 12121;    // communication port number
 DatagramSocket sock; // multi-purpose UDP socket

 // GUI elements
 TextField name;  // top text field
 TextArea disp;   // main text area
 TextField input; // bottom text field
 Button send;     // obvious 
 Button connect;  // not really "connecting" but close enough

 Map lookupTable; // keeps track of which user(name) is at which IP address

// constructor, throws any Exception because I was too lazy to list each one that could happen
// NOT A BEST PRACTICE
public uChat() throws Exception {
 super("uChat"); // call superclass constructor: Frame(String s); sets window title

 // retrieve broadcast IP address, method may (but shouldn't with a numerical address) throw UnknownHostException
 addrs = InetAddress.getByName("255.255.255.255");

 // initialze Socket, and bind to the port
 sock = new DatagramSocket(port);

 // initialize the lookup table as a HashMap
 lookupTable = new HashMap();

 // set up GUI elements
 disp = new TextArea("",0,0,TextArea.SCROLLBARS_VERTICAL_ONLY); // no starting text, default height and width, scrollbar display policy
 input = new TextField();
 name = new TextField();
 send = new Button("Send");    // buttons need
 connect = new Button("Join"); // labels

 // prevent editing the message display box
 disp.setEditable(false);

 //GUI layout design can be pretty hairy

 // a java.awt.Panel is a simple container
 // constructor accept java.awt.LayoutManager as an arg, BorderLayout is a subtype
 Panel pnl1 = new Panel(new BorderLayout());

 // add an anonymous label, followed by our name field and connect button
 pnl1.add(new Label("Name:"), BorderLayout.WEST);
 pnl1.add(name, BorderLayout.CENTER);
 pnl1.add(connect, BorderLayout.EAST);

 // the lower Panel, with the input field and send button
 Panel pnl2 = new Panel(new BorderLayout());
 pnl2.add(input,BorderLayout.CENTER);
 pnl2.add(send,BorderLayout.EAST);

 // set the our layout and add the panels and display area
 setLayout(new BorderLayout());
 add(pnl1, BorderLayout.NORTH);
 add(disp, BorderLayout.CENTER);
 add(pnl2, BorderLayout.SOUTH);

 // set up a new thread and pass us as the Runnable
 Thread t = new Thread(this);
 // start the thread
 t.start();

 // add us as ActionListener for the main GUI elements
 send.addActionListener(this);
 connect.addActionListener(this);
 input.addActionListener(this);
 name.addActionListener(this);

 // add us as a WindowListener for ourself
 addWindowListener(this);

 // display the main window
 setVisible(true);
} // end of constructor

// override Frame.setVisible(boolean b) to add some functionallity
public void setVisible(boolean b) {
 super.setVisible(b); // call Frame.setVisible() to actually show/hide the window
 if(b) { // if we're being shown...
  pack(); // ... shrink/grow the window so that each element gets it's 'prefferred size"
  Dimension scrn = Toolkit.getDefaultToolkit().getScreenSize(); // get the screen's size (in pixels) and...
  // ... calculater a point exactly our size up and left from the bottom corner of the screen and move us there
  setLocation((scrn.width-this.getSize().width)/1,(scrn.height-this.getSize().height)/1);
  // the result of this is causing the window to appear in the lower-right corner of the screen
 }
} // end of setVisible

public static void main(String arg[]) { // this is actually a stub,
 // call the constructor (from inside a try block), but don't keep a reference to the created object
 // (it'll dislay itself, so we don't need to)
 try { new uChat(); }
 // catch any Exception that pops up and pass it to the handle(Excpetion) method (it's way below)
 catch(Exception e) { handle(e); }
} // end of main

// a beast of a method here, this is from the ActionListener interface
// it's called any time an ActionEvent occurs, like clicking a button or pressing enter in a text field
// it's pretty convoluted. I'll devote an entire post (or more) to explaining it later.
public void actionPerformed(ActionEvent evt) { /* left out for now */ }

// a "flag" to tell the listener thread to stop
boolean die = false;

// the run() method is from the java.lang.Runnable interface
// this code will run in a seperate thread
// it listens for incoming UDP packets, interprets them, and updated the display text area accordingly
// it's fairly complicated to, and will get it's own post later
public void run() {
 // this loop does the hard part
 while(!die) { /* left out for now */ }
 // we've been told to stop, but we have a little clean up to do
 try {
  sock.close(); // close the socket
 } catch(Exception e) { handle(e); }
}

// from the WindowListener interface, this method is called when the user asks the window to close by clicking it's exit button
// it does a little clean-up: announcing to other uChaters that we're leaving
public void windowClosing(WindowEvent evt) {
 setVisible(false); // hide the window

 // if we're connected
 if(connect.getLabel() == "Join") { //only send LEAV if we're JOINed
  try {
   //build and send packet announcing that we're leaving
   byte[] data = "LEAV".concat(name.getText()).getBytes("ISO-8859-1");
   DatagramPacket out = new DatagramPacket(data, data.length,addrs,port);
   sock.send(out);
  } catch(Exception e) { handle(e); } // if an exception occurs, pass it to handle(Exception)
 }

 // change the flag, telling the listener thread to stop
 die = true;

 // this frees all resources associated with this window, allowing the event-processing threads to stop
 dispose();

 // this method explicitly tells the JMV to exit, but isn't needed as all threads should be ready to stop
// System.exit(0);
}

// these are also part of the WindowListner interface, but aren't used by this program
public void windowOpened(WindowEvent evt) { }
public void windowClosed(WindowEvent evt) { }
public void windowIconified(WindowEvent evt) { }
public void windowDeiconified(WindowEvent evt) { }
public void windowActivated(WindowEvent evt) { }
public void windowDeactivated(WindowEvent evt) { }

// all purpose Exception handler.
// NOT REMOTELY A BEST PRACTICE but sufficient for this small program
// static, so it can be accessed from main()
public static void handle(Exception e) {
 // set up a pair of writers to convert the Excpetion's stack trace to a string
 StringWriter sb = new StringWriter();
 PrintWriter out = new PrintWriter(sb);

 // dump the stack trace to the above writer and System.out (aka STDOUT, aka the terminal window)
 e.printStackTrace(out);
 e.printStackTrace(System.out);

 // make a new text area, default sizes, with the stack trace (via the writers) as its content
 TextArea disp = new TextArea(sb.getBuffer().toString());

 // simple frame, set its layout
 Frame f0 = new Frame("Oops");
 f0.setLayout(new BorderLayout());

 // anonymous inner class as event listener for the frame, more in another post
 f0.addWindowListener(new WindowAdapter() {
  public void windowClosing(WindowEvent evt) { ((Window)evt.getSource()).dispose(); }
 });

 // add a label, then add the text area from above
 f0.add(new Label("Oops, something went wrong. uC may or may not still work."), BorderLayout.NORTH);
 f0.add(disp, BorderLayout.CENTER);

 // pack() and show the frame
 f0.pack();
 f0.setVisible(true);
 // if you crash uChat (hint: start another instance while one's running), you'll see this method
 // in action. it's not a pretty error message, and would tell your average user absolutely nothing.
 // to be honest, this was 75% to shut the compiler up about "uncaught exceptions", 25% for debugging
}

}

Hopefully, with what you already know and the comments to help with what you don't, most of that makes at least some sense.

Not sure what I'll cover next... there's 3 or 4 topics that need to be covered. I should probably talk about multi-threading; there's a fair bit of network communication going on (that'll be at least 2 posts); I could go into how the interface goes together; need to touch on inner classes, maybe exception handling.

Anyway, that should be easier to understand than what I'd posted before. I'll update the top-bar page in a couple minutes.

Part 1.3: Java Concepts Example

Yes, finally. Just source + inline comments here. You might want to copy-paste to avoid the text wrapping.
//no imports needed here

//abstract classes cannot be instantiated, only extended
abstract class Vehicle {
 //private member variables is good encapsulation, but subclasses need protected, which works just as well in this case
 protected final int fuelCapacity; // Java uses final to indicate a constant. I believe const works as well
 protected int fuelLevel;
 protected boolean running;

//Vehicle has to initalize the constant fuelCapacity
// this is also inderited by subclasses
public Vehicle(int fCap) {
 fuelCapacity = fCap;
 running = false;
}

public int getFuelCapacity() { return fuelCapacity; } // a practice of mine:
public int getFuelLevel()    { return fuelLevel;    } // making things line up
public boolean isRunning()   { return running;      }

// javadoc comment, not going into detail on that yet
/** returns true if full */
public boolean setFuelLevel(int x) {
 if(x > fuelCapacity) x = fuelCapacity; // encapsulation in action
 fuelLevel = x;
 return fuelLevel == fuelCapacity; // comparison, same an C++
}

// left up to subclasses to decide how this works
/** should return true if successful */
public abstract boolean start();

}// end of Vehicle

class Car extends Vehicle {
 public Car() {
  super(40); // calls super-class constructor
 }
 public boolean start() {
  if(running == true ) { return false; } // it's already running, so we can't start it
  running = true;
  return true;
 }
}

public class Example {
 public static void main(String[] args) {
  Car theCar = new Car();
  //Vehicle myRide = new Vehicle(); // compiler error, class is abstract
  Vehicle myRide = theCar; // works, Car is a subtype of Vehicle
  myRide.start();
  System.out.println(myRide.isRunning()); // prints true
 }
}

That should do it. Any questions, leave 'em in the comments.

I'll wait a couple days, but the next post should be the uChat source with comments similar to this. Then we'll go from there. The 3 main areas to cover are threads, network communication, and GUI creation. What sounds the most interesting?

Part 1.2: A few (nay, lot of) words on Java syntax and packages

I said I was going to post an example, but I decided I needed to cover this right quick first.

Syntax of a typical file
Not strictly syntax but still important is the usual layout of a Java source code file:
>import statements<

>public class, enum, or interface definition<

>optional non-public class, enum, and interface definitions<
That last part is important, and not necessarily obvious to someone new to Java. I won't go into detail on the hows and whys, just know that a public class must be declared in a file wit the same name, and a non-public class can generally only be used by other classes in the same source file. THIS IS NOT A BEST PRACTICE. But it is useful for a quick "hack" program like uChat.

Wondering what enums and interfaces are? I'll explain interfaces later, but enums are out for now. They can be useful but for now I don't plan to cover them here. import statements will be described below.

Syntax of a typical class (includes methods and variables)
modifiers are not exhaustive, only the common ones are listed
[>access modifier, usually "public"<] [abstract] class >name< [extends >superclass<] [implements >interface<[, >more interfaces<] {

/* variable definitions */
>access modifier< [static] >data type< >name< [= >value<] [, >name2< [= >value2<];

/* method definitions */
>access modifier< [static] >return type, must be a data type or "void"< >name<[ ]([>data type< >name<[, >data type< >name<]) { >body< }

/* method required if class is to be run as a program */
public static void main(String[] >name, usually "args", but can be anything<) { >body< }

/* constructor definitions */
// constructors are used to create objects, they set up the object's internal state
// they look like a method, except they canNOT be static and have no return type
>access modifier, usually "public"< >name, must be the same as the class<[ ]([>parameter list, same as a method<] { >body< }

} // end of class
I hope all that makes sense. [this is optional] >this should be replaced with something appropriate<


Packages
If classes are templates for objects, then packages are books of templates. Packages are used to group classes together; generally classes that are used together for a given task will be in the same package.

For example the java.awt package contains the Abstract Windowing Toolkit, which can be used for creating GUIs. Similarly, the java.awt.event package contains classes for handling events "fired" by a user interacting with GUI elements (a button press, or a mouse movement for example).

The java.awt.event package is also an example of a package contained in another package. Packages are a bit like folders (or directories) on your computer. Some of the standard packages in the Java Library:
  • java -- the "standard" Java libraries, contains only other packages
  • java.awt -- the Abstract Windowing Toolkit, older library for designing GUIs and what uChat uses
  • java.lang -- automatically imported for every source file, contains the System class among many others
  • java.io -- classes for file I/O and filesystem access
  • java.net -- classes for network operations: sending and receiving via TCP and UDP, managing network addresses (DNS names, IPv4 and IPv6), depends on several classes in java.io
  • java.util -- a number of useful classes, includes the Collections Framework (lists, stacks, etc.) and the Random class
  • javax -- the "expansion" Java libraries; no, I'm not entirely sure what that means
  • javax.swing -- Swing, alternate (and preferred) GUI toolkit, duplicates and expands on the functionality of java.awt
Finally importing
import statements allow you use a class in a package with its short name rather than its long one. For example, in the java.awt package is the Button class; its full, long name is java.awt.Button. However if you import it, you can call it simply Button. import statements come in 2 varieties: single class and entire package.

Example:
import java.awt.Button;
import java.util.*;

The first imports java.awt.Button but not java.awt.TextArea. The second imports everything in java.util. It's generally easier to import an entire package. I know of no advantage to importing single classes.

Okay, next time: Example.
Then, we'll get started on uChat.

Sunday, August 22

Part 1.1: Basic Java/Programming Concepts

I won't bore you with the distinction between machine language and high-level code. Instead I'll hit some key terms (in no particular order) with a few examples.

Class: A class is basically the same as a "type". It defines a type of object, what it knows (variables) and what it can do (methods). You don't really use a class directly, you create objects from a class and uses those. There are exceptions to this rule, I'll go into a bit more detail later.

Object: An instance of a class. These can be created, destroyed, passed around, etc. If Dog is a class, then lassie is an object of class Dog. Each object has it's own independent copy of the variables defined in it's class. lassie's weight is different from toto's weight, but since the variable weight is defined in Dog you know that they both have a weight.

Function: a named block of code that can be called repeatedly. very similar to a method. in fact, there are no functions in Java, only methods.

Method: a function that is declared in a class, and runs within the context of an object. Example: Dog defines getWeight() (an accessor method, see Encapsulation), therefore you can ask and instance of Dog for its weight. since the method runs in the context of its object, it can return the appropriate weight value.

Encapsulation: the practice of hiding as much of an object's internal data as possible, exposing only what's needed via accessors ("get" methods) and mutators ("set" methods). this allows for validity checking, among other things.

Subclass: a class that extends another class, adding and/or changing some functionality. For example, you have a generic Vehicle class, and subclasses Car, Truck and maybe even Segway. They all have certain things in common, and these common properties can be defined in the "superclass" Vehicle. This is the basis of inheritance.

A quick break from terms to talk about variable types, classes, and objects. The type that a variable is declared as determines what objects it can contain. A variable declared with public Vehicle myRide; can hold an object of type Vehicle or any subclass of Vehicle. This is a very important concept, and allows for...

Polymorphism: Long word for a simple concept: using a subclass as it's superclass. Understand that? Not so much? Here's an example, let's say in your Vehicle class you defined a start() method. Thanks to inheritance, this means that you can tell any Vehicle (even if it's really a Car) to start. Polymorphism is when a subclass changes what is actually does to accomplish the task. How a car starts will be different from how a segway starts, but thanks to polymorphism, you don't have to worry about the details.

Wow that's a lot of stuff... and not too many examples. Check back next post for a nice example of most of these concepts.

Saturday, August 21

Part Zero: Setting up your Development Environment

If you've already got your feet wet with a little Java development, you can probably skip this post, but I'd still recommend skimming it so you've got an idea of what I'll be working with.

Alrighty, so, what do you need to do these tutorials?
  • A computer, any fairly new machine will do.
  • A JDK (Java Development Kit). On Windows, the the official Sun--I mean Oracle-- JDK is probably the best way to go, find it here. (You need the Java SE JDK, not the JRE or the Jave EE JDK. Yeah it can be a bit confusing.) If you're on a Linux or BSD machine, try searching your distro's package repository first. I believe there're alternatives to the official JDK, but use the official one unless you know what you're doing.
  • (optional) an IDE, such as NetBeans or Eclipse. I don't use one personally, but they can be very helpful.

Got all that? Great.

From here out, I'm going to assume you know how to compile and run your Java code.

I'll also assume you've got at least a basic knowledge of Java syntax, at least enough to make a "Hello World" program.

I recommend you make a folder named "java programs" or somesuch, a central place to keep all your projects. Your IDE may have a method of separating projects.

Let's get this thing started!

Alright! Here we go!

So, over the course of the next days/weeks/months, I'll be posting tutorials on the Java programming language here. For now the goal is the teach you everything you need to know to re-create uChat, a small network chat program I made over the course of a few days between classes.

Before I start on the tutorials, a bit more about uChat:
Source: 210 lines (current version, very few comments), 6.06Kb
Compiled: 7.17Kb in 2 class files
Packaged into JAR: 4.43Kb
UI: simple GUI
Network protocol: simple custom messages via UDP broadcast, no server needed!
Build method: quick and dirty MS batch file, because i'm too lazy to type 3 commands

MediaFire folder includes the source code, build script, and JAR.
Download the JAR and run it to see the program in action. Can't do much if you're on one computer, try it on a network with family/friends.
The source code's pretty cryptic, there's a lot going on in those 210 lines and not many comments explaining things.
Drop the build script in a folder with the source and click it to make the JAR. (Assuming you've got the JDK installed properly.)

If the link doesn't work, someone let me know in the comments and I'll see about fixing it.

That's all for now. Next time I'll go over what you should already have/know.

EDIT: I've added the source for uChat and my build script as a separate page. Don't worry about the MediaFire link.