Showing posts with label JAVA. Show all posts
Showing posts with label JAVA. Show all posts

Saturday, 29 September 2012

Explaining Java's Graphics System | Java's Poor Documentation

One of the hurdles in teaching graphics early is that Java handles graphics in a way that's hard to explain. This results in the graphics code that's handed to the student being treated as a piece of "black magic" for some time. At least with Swing being a standard part of Java now (though the observant student will wonder about that javax.swing thing) it appears more functional.

Sun's explanation makes interesting reading. If you're into doing jigsaw puzzles, this will be right up your alley. I especially like this particular comment near the beginning:

Both the AWT (abstract windowing toolkit) and Swing provide such a [graphics] framework. But the APIs that implement it are not well understood by some developers -- a problem that has led to programs not performing as well as they could.

Since this basically translates as, "Bad programs are written by programmers who can't read our minds," it's not a very flattering comment for Sun's readers.

Thursday, 27 September 2012

Mini-Review: Head First Java, 2nd ed. by Kathy Sierra and Bert Bates

Head First Java by Kathy Sierra and Bert Bates, cover image.
Head First Java, 2nd Edition
Head First Java is a great book for describing many of the confusing aspects of the Java language. It is easy to read, written in a light style, and it uses lots of graphics to break up long runs of text. Many of the graphics in the book illustrate key concepts of Java.

Not For Raw Beginners, But Close to It

For an experienced programmer new to Java, it can be used to learn enough about Java to get a strong basis in the language. It covers a lot of the language, enough to get someone from just starting out to the point where they're capable of carrying on learning with the official documentation or books on specific programming subjects within Java. It starts out at a point that will probably not be basic enough for non-programmers to start learning, but if the non-programmer has a mentor, or another book specifically intended for non-programmers, it will make an excellent supplement.

Trying Out LiveCDs

I'm still looking for a Linux or FreeBSD LiveCD for my high school computer class. I've had some success, but there's more to do. The idea is to have an OS disk that we'd run off of during class with the tools we need all there, ready to go.

No Room, No Room!

The computers in our lab at school have very limited disk space. Windows XP is installed on them, along with programs needed for other classes. That doesn't leave much room for graphics programs and development systems that I'd like to use for my classes, both the middle school and high school classes. So I thought I could use LiveCDs to solve the problem. Only the student's data files would need to be stored on the hard disk.

OpenSolaris

My OpenSolaris LiveCD arrived yesterday and I've had a chance to get a first brief look at it. I ordered it as part of my search for a LiveCD that I can use as a development environment for my high school computer class. I chose OpenSolaris in part because it's not already represented in the school's computer lab (I try to expose my students to as many different OSes as I can), I like Solaris in general (ever since it got over its teething pains after the change from SunOS), and I figured there'd be a high likelihood of the JDK being pre-installed on it.

It started up fine on my iMac (Core2Duo), and presented me with a very nice desktop. It's got some nice apps installed. The audio didn't work, even though it claimed to have a driver for it, and neither the ethernet or wireless networks had compatible drivers, which was disappointing.

No JDK? On a Sun OS? Really?

A bigger disappointment was the lack of a JDK. The JRE was there, but no JDK. In fact, I didn't find any development tools on the disk at all, except for python.

I realize that the space on a CD is pretty limited when delivering a modern OS, but it seems to me that if there's room for lots of media-related apps and sample media for them on a disk, there's room for some developer tools, too.

Certainly you'd think Sun would want to make the Java SE's JDK the 21st-century's equivalent to BASIC or K&R C? I guess python's got that role, it's just a shame that python doesn't address more of the system without having to use platform-specific APIs.

Keep Looking

Well, OpenSolaris isn't entirely out of the running for my class. This particular LiveCD is, but after some searching for a LiveCD that contains the JDK I turned up BeleniX. I downloaded the latest ISO last night, hopefully I'll have time to burn it and give it a spin soon. The list of packages claims that it has the JDK version 5 (presumably 1.5), which is good enough for a beginner's class, though I'd prefer 1.6. At least I'll have the Scanner class.

Wednesday, 26 September 2012

Why I Taught Programming with Java

I teach a high school computer class, and this last year we spent a semester learning programming. Picking the computer language we'd use was a lot tougher than I expected it to be. I looked at a lot of languages, and a lot of implementations of those languages. I ended up using Java.

I wanted a language that the students could use on their own, outside of class, to do real things. The language also had to be supported on multiple platforms, with the same syntax and libraries/classes on at least the major desktop OSes. It also had to be free, in the sense that there'd be no license fees for the school

On top of that, I wanted it to be fun, something that would let the students play with graphics and sound. Console-mode text just didn't cut it.

Now, in this day and age you wouldn't think it's expecting too much to have a programming language support features like graphics and sound, right? Apparently the language developers think it is. They rely on hooks to proprietary APIs, mostly, meaning that the code to open a window on platform A is completely different than that on platform B.

I'm not talking implementing keywords for controlling specular reflections and bitplane operations, here. I'm just looking for windows and some basic drawing primitives in the way of graphics. For sound, the ability to play a tone or a simple audio file would be plenty.

I was hoping to use a language with a clean, simple syntax like ruby or python. But I didn't find an implementation of either that met my needs. Jython came close, but the hurdle of jumping the Java API barrier to get the graphics and sound undid all the good that the core python would do--it would be easier to just teach Java from the outset.

I also considered going with Berkeley Logo. I like Logo a lot, basically it's LISP with some of the historically-established keywords cleaned up. I may use it this upcoming year with my middle school class. But for my high schoolers, I wanted something with more of a real world presence. Something they could keep moving forward with without having to change horses. Honestly, an open LISP implementation with platform-independent graphics and sound capabilities would fit the bill. One look at Y Combinator is all it takes to see that LISP is alive in the real world. I looked at some LISP implementations, I'll be looking at some more, but in the time I had I didn't find something that did what I was looking for.

Less Than Perfect
There were still some snags with Java, though. Installing the SDK on the school's Windows systems was a pain. The extra step of changing the command path was annoying for me, and for my students who went to install it on their home systems it became an insurmountable obstacle in about half the cases. OK, to tech-heads this probably seems like foolishness. Some may say that if they're stopped by this they have no business programming. I don't see it that way, and I don't take kindly to folks who think unnecessary complications in installing and using software ought to be used as a worthiness test for beginners. Beginners are beginners, and they ought to be able to focus on the one thing they're working on learning at any one time.

And, face it, as Windows users they're not used to install procedures any more complex than spinning a disk and clicking on a button. It's a shame users of all platforms couldn't have it that good.

As the aficionados of the scripting languages point out, Java's syntax isn't a simple and straightforward as it could be. To new programmers its insistence on certain forms of capitalization make it seem pretty fussy, for example, and dots meaning one thing in an import statement and another with invoking methods and members is more class time lost.

I used a Java textbook for non-programmers in an attempt to make my life a bit easier. I wasn't entirely satisfied with the any of the available Java programming books I was able to review before we got started with Java in class. As basic Computer Science books, I think they were fine. As introductions to casual programming, there were none that fit the bill. I'll try to do mini-reviews of the books I looked at and used in some future post. But my main concern was that the fun stuff--graphics and sound--was all left till late in the books. I had expected to find something that presents some basics like a JFrame and paintComponent early on, then plays with flow control constructs and such by using graphics within them. Unfortunately, I didn't find any such Java books for non-programmers (or for programmers but basic enough that I could make up the difference.)

Looking Forward

I'm planning on spending a semester on programming again in this upcoming school year. I haven't decided if I'm going to stick with Java, though the default will be doing so. If I do stick with Java, I may create a LiveCD of some sort with the SDK and a basic IDE on it, and distribute it to the class. This could get rid of some problems I had last year, like dealing with some of Window's programmer-hostile features in class while neglecting the students on other OSes, as well as installation of the SDK on the computers in the school's lab (the non-Mac OS ones, that is.) It'll also mean that the student can take the CD home and have the same development environment there as in class.

I'm also still looking at other options. Because I still think it's worthwhile to have some graphics and sound in an introductory class, and because I still want the students to be producing portable programs, I'm concentrating on the language implementations that compile to Java bytecode. If I find a language that doesn't have some of Java's gotchas for beginners, it won't be any worst to install its compiler (except that I'll have to add it to the OS X systems as well as the others, unlike the Java SDK.)

Groovy is one possibility I've found so far. JavaFX may be another. Whatever language I choose, I may still go with using a LiveCD of a BSD, Linux, or maybe even OpenSolaris depending on what I can find that works well with the lab's computers and is likely to work well with most students' home systems.

I can tell you this, though. As "bad" as it was, it's times like this that I really, really miss those old 8-bit computers with BASIC on them.

Friday, 21 September 2012

Java's Assignment Operators

An assignment operator is a way of putting a new value into a variable.

I covered these briefly in Doing Math in Java, Part 1. Now I'll go into a bit more detail.

The Simple Assignment Operator

The simple assignment operator is =.

It places the value from the expression on its right side into the variable on its left.
This is covered in detail in Left Becomes Right.

Also see the Java Language Specification: The Simple Assignment Operator.

The Compound Assignment Operators

The compound assignment operators are:
+=, "plus-equals",
-=, "minus-equals",
*=, "times-equals" or "star-equals",
/=, "divided by-equals" or "slash-equals",
%=, "remainder-equals" or "percent-equals",
&=, "and-equals",
|=, "or-equals",
^=, "exor-equals" or "caret-equals",
>>=, "signed-shift-right-equals",
<<=, "shift-left-equals",
>>>=, "unsigned-shift-right-equals".

Commonality
Each of these operators has a variable to assign a value to before it, and an expression that results in a value after it:
variable operator expression

The expression has to result in a value that is compatible with variable's type.

Java will calculate the value of expression,

perform the calculation variable optype expression, where optype is the assignment operator without the equals sign.

Then it will place the result of that calculation into variable.

+=, "Plus-Equals"
Plus-equals adds the value after += to the original value of the variable, then puts the result into the variable.

-=, "Minus-Equals"
This subtracts the value after the operator from the original value in the variable, then stores the result in the variable.

*=, "Times-Equals"
Multiply the variable by the value on the right of the operator, put the result in variable.

/=, "Divided by-Equals"
Same as the above, but for division.

%=, "Remainder-Equals"
This finds the remainder of the variable's initial value divided by the value after the operator. That remainder is then put into the variable.

See Java's Modulo Operator--Wrapping Around for more information on how the remainder (or modulo) operator % works.

&=, "And-Equals"
And-equals does a bit-wise AND of the value after the assignment operator with the original value of the variable, then puts the results in the variable.

|=, "Or-Equals"
Or-equals does a bit-wise OR of the variable and the value after the operator. The result is placed in the variable.

^=, "Exor-Equals"
Exor-equals is short of Exclusive-Or Equals (and it is often written xor-equals). It does a bitwise exclusive-or of the variable and the value after the assignment operator, then puts the result into the variable.

>>=, "Signed-Shift-Right-Equals"
This does a signed right shift of the variable a number of times equal to the expression after the assignment operator. The result is placed in variable.

<<=, "Shift-Left-Equals"
This does the same thing as signed-shift-right-equals, except it does a signed left shift (each bit in the variable gets moved to the left expression times.

>>>=, "Unsigned-Shift-Right-Equals"
This one moves all the bits, unlike the signed shifts which leave the sign bit (highest order bit) alone.

Not Quite the Whole Story
That covers how these operators behave with numerical and other simple values. These operators have other behaviors when used with Strings, Arrays, and other complex value types. That goes beyond the scope of this article, however, more on that can be found at the links given under "Additional Information".

Additional Information
See the Java Language Specification: Compound Assignment Operators, Multiplicative Operators, Additive Operators, Bit-wise and Logical Operators.

Java's Modulo Function--Wrapping Around

I've previously discussed operators in Java, where I gave a brief introduction to the modulo operator, %.

The percent sign is used in many computer languages as a brief, single-character symbol for the remainder of a division, not for a percentage of a number, as you might expect.

What's Left Over

In many calculations in normal day to day life, the remainder of a division is not very important. It's just the odd change left over at the end of doing division. With computer programs, however, modulos can be very useful and powerful.

One of its most important uses is to limit the range of a value. For example, if we're only interested in having a value be a number from 0 to 99, and any value over that is something we don't want, we can use modulo as a way of cutting any number we get down to size. Since the remainder of a division can never be as large or larger than the divisor, we know that any remainder from a division by 100 can never be more than 99 (in integers.) So we can take any number, find the modulo by some number that we want as an unreachable cap on our values, and never get a number that's too big.

limitedNumber = someNumber % 100

limitedNumber will never be higher than 99.

Real World Analogies

A real world version of this is a knob that you can turn around without a stop on it. The knob's setting can vary over a range of values all the way around it. But when you turn it past some point, it goes from its highest setting to its lowest setting.

Radio dial, image by John McComb of Oakland, CA.

For example, a radio dial that goes up in frequency until you hit the top of the radio band, then starts tuning over again from the bottom of the band.

Computer Applications

One of the most common uses of the modulo in computer programs uses that same ability with computer graphics. How many computer games have you seen where an object goes off one side of the computer's screen then reappears on the other side? That's an example of the modulo function. Let's look at an asteroid object that has its horizontal location on screen tracked by the member variable xLoc (short for x location):

Class Asteroid{
    int xLoc, yLoc, xSpeed, ySpeed, size;
    .
    .
    .
}


We'll assume the class has all the methods it needs to do what Asteroids do. Our instance is:

Asteroid asteroid = new Asteroid();
(If this is unfamiliar to you, you may want to read Creating a Java Variable, Two Steps.)

Now let's say our asteroid is presented on a screen area that is 800 pixels wide and 600 pixels high. That means our xLoc value can vary from 0 (the leftmost location on screen) to 799 (the rightmost location on screen) since we have a screen area 800 pixels wide. Remember, when we start counting at 0 our highest number is one less than the total number of pixels.

We can move our asteroid from left to right as follows:

xLoc = xLoc + xSpeed;

Where xSpeed is how fast we're moving across the screen.

The problem is, what do we do when we hit the right edge of the screen? That is, what do we do when xLoc is higher than 799?

If we want our asteroid to "wrap around" from the right side to the left side of our screen, the modulo operator is just what we want. We can do this to make it wrap around that way:

xLoc = xLoc + xSpeed;
xLoc = xLoc % 800; // Hard-coded screen width, for now.


That will make xLoc always be from 0 (when there is a zero remainder) to 799 (the highest possible remainder when dividing by 800.)

We might have a method in Asteroid like the following:

public int moveHoriz(int howFar){
  // Moves the Asteroid horizontally by howFar pixels on an 800 pixel wide screen.
  // returns the new pixel location.
  return (xLoc + howFar) % 800;
}


This glosses over a few other problems (like going from the left edge of the screen to the right), but illustrates the use of modulo to bring the object around from right to left again.


An Expanded Example

Here's a more developed example that deals with speeds higher than the screen width, and wraps both ways:

public int moveHoriz(int howFar){
  // Moves the Asteroid horizontally by howFar pixels on a screen.
  // It returns the new horizontal pixel location.

  // We have a screen width available to us in member variable xWidth,
  // and our x location in xLoc.
  // Wraps from right to left, or left to right.

  //Use modulo to trim speed if it's too high.
  if (howFar > xWidth) howFar %= xWidth;

  // Calculate the new x location and return it.
  return (xLoc + howFar + xWidth) % xWidth;
}

Java Introspection and Using Collections without Generics

In my prior article on Generics we looked at how to use Generics to associate at type with data stored in a Collection.

You might wonder why would anyone want to store information in a Collection without its type being preserved. Well, it's possible that you'd want to store many Objects of different types in one collection. In that case, the only parent those types might have in common is java.lang.Object. So using a Generic won't do you any good.

But, once you pull that data back out of the Collection, how do you find out what it was?

Fortunately, the object itself has that information stored with it.

There are two easy ways to find out what it is. instanceof can test if it is a specific type of Object:
if (anObject instanceof String) { aString = (String)anObject); }


You can also have an Object tell you its type:
Class myClass = anObject.getClass();

or
String myClassName = anObject.getClass().getName();


A look at the documentation for Object and Class gives all sorts of useful methods for dealing with classes of data objects in Java.

Here's some sample code:
import java.util.*;

public class NoGenerics2{
// This is an example of using introspection
// to determine types of Objects stored in a
// Collection without a Generic declaration.

  public static void main(String[] arg){
    ArrayList myList = new ArrayList(); // No Generic  declaration.
    String myString="Boss Moss";
    String yourString="Snorkledorf";

    // put the strings into the List
    myList.add(myString);
    myList.add(yourString);

    for (Object anObject: myList){
      System.out.println(anObject.getClass().getName());
      if (anObject instanceof String){
        String aString = (String)anObject; 
      }
      else{
        System.out.println("Not a String, Sheriff!");
      }
    }
  }
}

Generics in Java

Generics are an oddly-named thing in Java that associate objects stored in a Collection with a particular type. Let's take a look at a piece of code that uses a Collection to store some Strings. It uses an ArrayList. Here's the code:

import java.util.*;
public class NoGenerics{
// This is an example of what happens 
// when you don't declare a class
// for a Collection using Generics. 
// It won't compile!

  public static void main(String[] arg){
    // No Generic  declaration.
    ArrayList myList = new ArrayList();
    String myString="Boss Moss";
    String yourString="Snorkledorf";

    // put the strings into the ArrayList
    myList.add(myString);
    myList.add(yourString);

    for (String aString: myList){
    // We can't do String methods on the items from myList.
      if (aString.startsWith("Boss")){
        System.out.println(aString + ":");
        System.out.println("Make sure you spell it right!");
      }
      else{
        System.out.println(aString + ":");
        System.out.println("I am so pretty!");
      }
    }
  }
}

What happens here to upset javac is that once the String is placed in the ArrayList, its type is lost, and it is known only as an Object. To be treated as a String again, it would have to be cast as a String. If any errors are made in casting the data, the program will fail at runtime, not when it is being compiled--when the programmer has it in their hands to fix it.

Feel free to take the above code and try to compile it to see the error you'll get. It is instructive.


The Fix for Lost Types

In Java version 1.5 "Generics" were added to fix this. Now Collections like the ArrayList can associate a type with the data put in them, and the compiler can do type checking. Here's the above code, with the Generic declaration added:

import java.util.*;

public class Generics{
// This is an example of what happens 
// when you declare a data class
// for a Collection using Generics.

  public static void main(String[] arg){
    // Generic  declaration.
    ArrayList myList = new ArrayList();
    String myString="Boss Moss";
    String yourString="Snorkledorf";

    // put the strings into the ArrayList
    myList.add(myString);
    myList.add(yourString);

    for (String aString: myList){
    // Now when we can do String methods on the List items.
      if (aString.startsWith("Boss")){
        System.out.println(aString + ":");
        System.out.println("Make sure you spell it right!");
      }
      else{
        System.out.println(aString + ":");
        System.out.println("I am so pretty!");
      }
    }
  }
}

Generics = Typed Collections
So if you are going to use a collection on Objects all of a specific type (rather than mixing and matching), put on a Generic declaration.

Java under Mac OS X 10.7 Lion

Lion is the first version of Mac OS X that doesn't come with Java already installed. Earlier versions not only had the Java Virtual Machine or runtime element installed, but they also had the JDK installed, which is the part that lets you write your own Java programs.

Once, Java was an important part of Apple's strategy. They maintained their own version of Java for the Mac and encouraged its use by developers every bit as much as they encouraged the use of Objective-C.

The success of the iPhone and the iPad have changed that, however. Apple decided that Java would not be part of those platforms. The lack of Java is the very reason I've chosen not to get an iPhone. Instead, I get phones with Java so that I can run my own Java applications that I write for my own use.

Now that Lion doesn't have Java pre-installed, what do you do? Fortunately, a deal has been struck where Java is still available for the Mac. It's much the same arrangement as Java for other platforms. In fact, it's easier to install Java on your Mac than any other platform. And you get the JDK along with the runtime (JVM) environment.

Simply use Finder to go to Applications=>Utilities. There, start Terminal. Once Terminal starts, type in the command 'javac'. Your Mac will tell you that Java isn't installed, and let you install it.

I'm pleased that the Mac has not entirely forsaken Java, even if it's not an integral part as it has been. The basic software supplied with the Mac has declined severely over the past few years, but fortunately Java is still available and easy to install when you want it.

Embedded Java

Embedded Java sounds almost like an oxymoron. Taking a high level, large, interpreted language like Java and using it in an application field dominated by assembly and C certainly seems odd. But it's a reality.

For one thing, the microcontrollers of today are not the limited 1K to 2K ROM, 8-bit, 200kHz machine cycle rate CPUs of yesteryear. They're more powerful than the desktop systems of 10-15 years ago in many cases. And we were playing Quake II on those. So maybe Java isn't quite such a stretch, after all.

NanoVM is a small, subscale Java-ish virtual machine that runs on tiny 8-bit microcontrollers like the AVR ATMega8. It's not a full Java, but it covers most of what's interesting to the microcontroller programmer.

The JStamp is a Java development system for the aJile micros. It's also not a full Java SE implementation (what would you do with the extra bits, even if it was?), but it is a verifiable real-time Java system for embedded development.

Also, IS2T has MicroEJ, another embedded Java for a number of processors. Everything from the basics of execution and I/O up to GUIs, SOAs, and safety-critical libraries are available.

I still remember when it was considered laughable to consider a C-language embedded development system. But it has either nudged assembly out of the top spot for embedded development or is close to it, now. Any language that is popular enough can be brought to the task now, and Java is no exception.

It's all just a bunch of ones and zeroes in the end.

Mobile Java

One of the nice things about Java is that is supported on more than desktop platforms, and has been for a long time. This means there is not only a large library of existing software, but also well-tuned development systems to use with mobile platforms.

By "mobile platform", I'm referring to smartphones and tablets. There are other mobile platforms, but these are the most common ones. Netbooks may also run a "mobile" operating system, or they may run a normal desktop OS. Those that run a normal desktop OS will run normal Java SE applications. Java SE is "Java, Standard Edition", the version that typically runs on a desktop or laptop computer.

Java ME is Java, Mobile Edition. It runs on most smartphones, and many tablets. It is very similar to the Java SE version covered in most of my articles. In fact, it is possible to write many applications using a subset of Java that will run without change under both Java SE and Java ME.

But normally a Java ME application will use user interface objects and interfaces that are specific to Java ME. In many ways these are more sophisticated than the ones for Java SE. Creating many types of graphical interfaces, such as tiled graphics, is easier in the mobile edition than in standard Java.

I have been writing small, simple applications for my cellphones for about ten years now. It's nice to be able to write your own little application for your own unique needs. I started writing Java applications for my Nokia 3650, called a "feature phone" at the time I got it. It was a Symbian Series 60 phone that ran an early version of Java ME with a very basic library of GUI features.

My next phone was a step up the Java ladder. It was a Sciphone G2, a fake Android phone. I didn't mind that it was "fake", it ran a real version of Java ME with updated GUI capabilities, which made it far easier to write applications for.

My current phone is a Blackberry Curve 8900. It runs Java ME with all the latest bells and whistles, plus a lot of Blackberry add-ons that make it easy to access the phone's features.

With my Nokia, I had a special Java development environment provided by Nokia that included a simulation of my phone, so that I could see how my programs would run before I put them on the phone. With the G2 I was on my own. I ran a standard Java ME development environment from within Eclipse, a great Java integrated development environment. The version linked above is a version specific to Java ME.

Now I'm back to having a development environment provided by my phone's maker. I have a program that simulates my phone on my computer, which again allows me to try out my programs before I put them on the phone (with my G2 I tested them as well as I could, then loaded them on the phone and hoped for the best.) It is build on Eclipse, so it is still very familiar. There is also a slew of information on the Blackberry site (linked above) about Java development.

Unfortunately, the tutorials on the site don't exactly match the actual current version of the software, but it's close enough it's not too hard to figure out. One thing that confused me, however, is the installation instructions. I thought I had to install the version of Eclipse they called for before installing the "Blackberry Java Eclipse Add-On". It's an add-on, right?

Well, it turns out that the "add-on" from Blackberry is actually the entire thing, Eclipse and all. So you just need to do that one download to get the development environment. Then download the simulator for your phone and any others you want to test your software on. Finally, apply for a signature key to make it so that you can "sign" your software to allow it to be installed on the phone through the software manager or Over The Air (OTA) when using the Blackberry-specific libraries.

If you'd rather not do this, you can develop software using a plain-jane version of Java ME, then transfer the software to your phone however you please. I put the software I developed for my Sciphone G2 on the memory card for my Blackberry, and it runs just fine.

Translating applications between Java SE and Java ME can be simple for ones with minimal amounts of graphics, like programs that mainly use text, buttons, and text entry boxes for communication. Things like games, with a more involved use of graphics, take more effort to translate between the two versions of Java. For these, I usually re-use the game logic code without changes, then rewrite the graphical display parts of the program from scratch. Because I use good object-oriented coding practices (most of the time), this isn't too much effort.

Java ME applets are easy to translate, though I write almost all of my Java software as applications now.

Numeric Literal Values

Java 7 has added a new feature, binary literals for integer number types (byte, short, int, and long.) Before we can get excited about this, we need to know what that means. In earlier versions of Java, we have had several other types of literal value.

Let's Get Literal

What is a "literal"? A literal is an explicit value. For example, in this line:

int number=123;

the value 123 is a "literal". Since it's a normal base-10 value, we might say it is a "decimal literal". Decimal values don't have to be marked in any special way.

A hexadecimal literal looks like this:

int number=0x007b;

The value 0x007b is a hexadecimal (base 16) number that is expressed literally (stated explicitly.) The 0x at the beginning is what marks it as a hexadecimal value. The leading zero shows that it's a numerical value, not a variable name or keyword or something like that. The x marks it as a hexadecimal number.

Hexadecimal numbers take binary values four bits at a time (a bit is a single one or zero value) and puts them into a single digit. Octal (base 8) digits each represent the values of three bits.

To tell Java you're using an octal value, place a leading zero in front of the number itself:

int number=0173;

Here the number 0173 is an octal value equal to 123 in decimal. If we accidentally put a zero in front of a decimal integer, we'll either get an error (if we use the digits 8 or 9 in that number) or the value will be interpreted incorrectly. For example, if we want to put the value of one hundred twenty-three into a variable, but instead of the line we have above we accidentally add a zero, like this:


int number=0123;

The value of the number will be interpreted as eighty-three, not one hundred twenty-three. So watch out for that.

New for Java 7--Binary Literals
In Java 7 we get a new ability, the use of binary numbers. Since you know that you can encode binary values into both octal and hex either three or four bits at a time, this may not seem like a really big deal. In fact, there's been a request to add this feature to Java for a long time, but it's been low priority.

But now it's finally here.

So you can define values as individual bits, like this:

int number=0b01111011;

That's the binary for one hundred twenty-three, by the way. Why is this important?

As Java becomes more mature, and more widely used, it is used in more places. Over time, high level languages that deal with things at a very abstract level tend to get used in more situations where it is nice to have the high level features while also having the ability to have low level control or simulation of the actual computer hardware. In cases like these, it is nice to be able to manipulate single bits in places where they represent specific individual signals in the computer system or simulation.

For example, let's say we want to recreate an old 1980s computer in a Java program, like a Commodore 64. The Commodore 64 reads several signal lines directly on its joystick ports. We want to be able to simulate the behavior of these ports so that we can play old C-64 games in our simulation. Each of the lines represents a switch in the joystick. So we may take a particular keypress and represent it as the following binary value:

byte stick_up=0b00001;

In this case, we show it setting the lowest order bit. We might have another like this:

byte fire_switch=0b100000;

Since these each equate to specific electrical signals that get "turned into bits" in the C-64's CIA chip, it's nice to be able to tell them to Java as bits. We could have used hex or octal, but it's a bit nicer to see them as individual bits.

Java Variable Value Assignment: Left Equals Right, Left Becomes Right

One of those things that vexes beginning programmers is assigning values to a variable in Java. Part of what makes it so vexing is that the problem is practically invisible to an experienced programmer. Another part of it is that we use the equals sign (=) to do the assignment.

Take a look at these statements:

int i = 1;
j=7;
7+count=c;
b+14=a+9;

The first two are fine (assuming that 7 is a valid value for whatever type of variable j is), but the last two are wrong.

Remember All That Algebra We Taught You? Well, We Broke It.

After you've gone to all the trouble to learn how to deal with things like 7+count=c and b+14=a+9 in algebra class, now we take what you know and turn it on its ear in programming class. Sweet, eh?

The problem is that the = we use in programming has pretty much nothing to do with the = that you use in math. It's just close enough to be confusing. In Java, the equals sign is an assignment operator, not an indicator of equality between values as it is in math. There is a comparison operator for equality in Java, it's ==, and we'll talk about it shortly. First, let's talk assignment.

Assignment

In computers, we use the term assignment to describe sticking a value into the computer's memory so that we can get it back later. It's like using the memory in a programmable calculator. We put some number into our calculator's memory so that we can get it back later for another part of our calculation. It's pretty much the same thing with computers.

With Java, we can store all kinds of values, not just numbers. We can store sections of text, called strings in a String variable, for example. (Java prefers the term "member" over variable, in general. For what we're talking about now, the two terms are interchangeable.) We can also store more than one thing at a time, like all the information about a bicycle in a Bicycle object that keeps track of a bicycle's color, frame size, tire size, gear ratios, etc., all together in one object.

But we're here to just look at assignment today, not the wide variety of things we can assign as values.

To store a value on a calculator, you use some key sequence like M+ or STO 00 to store the value in the calculator's display to memory. With Java, we use the equals sign to store some value on the right into whatever is on the left side of the equals sign. We read from left to right like this:

count = a;
"count equals a"

This means we take the value of a and place it in count. But a better way to read that equals sign is to use the word "becomes" instead of "equals":

count = 9;
"count becomes nine"

This makes it more obvious that we're putting in a new value that changes the value of count. In this case, we're putting in a value of 9. The statement up above would be "count becomes a" or, better yet, "count becomes a's value." Because what we're doing in count= a; is taking the value in variable a and copying it into count. If we then print the value in count, it will be the same as whatever is in a at that time.

We can also compute a value to put into our variable.

count = a + 1;
"count becomes a plus one"

This makes the value in count be one more than the current value of a.

What we can't do is change sides around the equals sign. In algebra, c = a + 1 is the same as a + 1 = c. But in Java that doesn't work:

a + 1 = count
This is wrong in Java. Does not compute. Norman, Norman, help me Norman!

We would be trying to make a+1 become the value in count. The problem is, you can't have a storage location named "a+1". Java doesn't see this the way your algebra trained eyes do.

Comparisons

In normal math, when we use the equals sign we are making a comparison. We are stating that what's on one side of the equals sign is the same as what's on the other side. For most algebra problems, we assume that the statement is true and try to find values for the variables that result in that.

Another use of equals in some math problems is to state that two things are equal when they may or may not be, then determine whether that statement is true or not. You remember those problems, they looked something like this:

State whether each of the following is true or false.
1. 11 = 6 + 5
2. 14 = 3 x 7
3 65 - 14 = 17 x 3


In Java, the equals sign is already used for assigning values to variables. How do we do a comparison to see whether it's true or not?

The == Operator

In some languages, = does both jobs. But in Java, there's a second operator for doing equality comparisons, ==, "equals equals". When we want to see if two values are the same, we compare them using a statement something like this:

if (count == 100) then stop();

This compares count to the value 100, and executes the method stop() if the result of the comparison is true.


The Dangers of the = Operator

Something to look out for is using = by accident in such a situation. Like this:

if (count = 100) then stop();
Don't do this if you want to compare count to 100!

What this does is assign the value 100 to count. If the assignment is successful (which it almost certainly will be, if the program compiles), the program will then do stop() every time it hits this statement! Because the assignment was successful, so the result is considered to be true.

Summary

The equals sign makes the variable on the left equal the computed value from the right side of the equals sign:

name = "Mergatroyd";
"name becomes Mergatroyd"

It doesn't work the other way around (putting something from the left into the variable on the right.)

If you want to compare to values to see if they're equal, use "equals equals":
if (state == "done") then exit();
"if state equals equals done then exit" or
"if state is equal to done then exit"

Doing Math in Java part 2:Functions

The basics of math in Java using operators was covered in Part 1: Operators. There I went over the standard operations built into the language itself, rather than in its APIs (libraries).

But that's hardly the end of useful math operations. Especially when doing graphics, where all those geometric and trigonometric functions come in so useful. Square root, cosine, absolute values, etc.

If you're wandering into the Java APIs unguided, the java.math package might catch your eye right away. Unfortunately, it's a false trail when what you're looking for is a simple general purpose math package (it's a nice special-purpose math package for particular sorts of calculation, however.)

What you really want is the java.lang.Math class, in the java.lang package.

This has most of the standard math functions you're used to. They're defined as static methods, so you don't need to create a Math object to use them. You just call them like this:

    float distance = Math.sqrt(dx*dx + dy*dy);
    float speed = Math.abs(velocity);


These call the square root function Math.sqrt() and absolute value function Math.abs(). There are a slew of others like degree to radian conversion, the standard trig functions, and so on.

Date Calculations

Calculations with dates are another standard sort of math that's not covered by standard operators. In the package java.util we've got the Calendar class. The Calendar class itself is an abstract class. This means that it's a class used to build other classes with, not to use directly. The GregorianCalendar class is a concrete implementation of Calendar that you can use directly. The Calendar object's add() method will add or subtract some amount of time--days, minutes, hours, etc.--to or from a given date (the date that the object is set to:

  1. Create a GregorianCalendar Object

  2. Set its date

  3. Use its add() method to add or subtract the time difference.

Example:
GregorianCalendar myDate;
myDate = new GregorianCalendar(2011, 6, 7); //set the date to 07 June 2011.
myDate.add(Calendar.Date, 165); // add 165 days to that date.


before(), after() and compareTo will return whether one date occurs before or after another. Computing the number of days between two dates is a bit more complex, unfortunately, as are similar calculations. Basically, the procedure is to use getTime() to convert both dates to time values, get the difference, then divide that by the time units you want to see the difference in (e.g. divide by 24 hours periods to get the difference in days.)

Unfortunately, the Calendar class demonstrates one of the problems with much of Java. It's an overly generalized class that prevents simple solutions to many simple and obvious problems. The older Date class took a more direct approach, but it has been deprecated in favor of the Calendar based classes. Unfortunately, even obtaining a printable date value according to the system's current locale takes a fair bit of set up in Java. A better solution would have been a very general class like Calendar behind a more usable class for solving conventional problems, but Java's development got it backward. We got the simple class first, it's inflexibility for solving certain problems resulted in criticism, then came a general class, which is no good at doing simple and obvious things for most users. The extra layer that we should have to make Calendar more usable has not yet appeared in the standard API (and possibly never will.)

So it takes a lot of code to do what should only take a line or two, when working with dates.

Still, give the Calendar and GregorianCalendar class a look-over. Even though it takes some extra code and set-up to do some simple tasks, the solutions to these problems are well established and many examples are available. It's just not as simple as System.out.println(myDate);

I'll be adding articles dealing specifically with dates myself at a future date.

Doing Math in Java part 1: Operators

One of the most valuable uses of a computer is...computing. That is, acting as a mathematical calculator. Java has a plethora of tools for doing computation.

Operators

The standard math functions that are built into the Java language are called operators. These are the sort of math functions you would expect to find on a simple calculator, plus some extras:


+ - * / % ++ --


There are other operators used for comparisons, these are the math operators. You can learn more about them in the Java Language Specification, specifically in Integer Operations, Floating-Point Operations, and more extensively through Chapter 15, Expressions.

+ and - do what you would expect, they add and subtract one value from another. * is the symbol used for multiplication, instead of the × used in math class. * is used because it's easier for the computer to recognize it as a math operator, × just looks like a letter 'x' to the computer. Similarly, / is used for division. The ÷ sign isn't on most keyboards, but / has been common on keyboards even before they were attached to computers.

The % sign doesn't do what you might, at first, expect. It doesn't calculate a percentage, as it does on most calculators. It returns the remainder of a division. For example, if you do 10/3 (ten divided by three), the result will be 3. But what if you want to get the remainder? That's what % does. 10%3 will return a value of 1. '%' is sometimes called "modulo". It's a bit of a misnomer, mathematically, but the use of the term is common and well understood, so it's not unusual to pronounce 10%3 as "ten modulo three". This is a very valuable function for keeping a value within a certain range, such as keeping an object located onscreen in graphics by having it "wrap" from one side of the screen to the other when it reaches an edge.

++ and -- are the "increment" and "decrement" operators. Increment means "go up by one unit", and decrement "go down by one unit". So if you've got a variable like:

int i = 5;

And you do i++, the value of i will become 6. Doing i-- will take away 1. ++ and -- can be placed either before or after the value they act on, for example:

number = i++;
count = --j;


There will be different effects on your program depending on whether they come before or after the value. You can find information on that in the Java Language Specification as well, in sections 15.14 and 15.15 which cover the two ways of using these operators. In general, it's best to stick to using them after your value until you understand the differences.

Assignment Operators

You can also do math as part of assigning a value. For example, let's say we want to add three to a value in our program. The obvious way to do this would be:

i = i + 3;

This takes the prior value of i, adds 3 to it, then puts the result back into variable i. With an assignment operator we can do the same thing more tersely:

i += 3;

We've combined the + with = to create an operator. This does the same thing as i = i + 3;. Your program doesn't care which way you type it. The same thing can be done with the other operators that take two values:

i *= 4; // Multiply i by four, store result back in i.
i /= 2; // Divide i in half.
i %= 3; // Put the remainder of i/3 in i.
i -= 7; //Subtract seven from i.


More Complex Math

This is what we can do with the basic math operators built into the language. To get more operations, like those found on a scientific or programmer's calculator, we use methods of some of the standard packages of Java. Which I'll cover in a future article.

Until then, have a look at java.lang.Math.

A Java CSV File Reader

One of the most common types of data file is a CSV (Comma Separated Value) file. They can be exported by many popular applications, notable spreadsheet programs like Excel and Numbers. They are easy to read into your Java programs once you know how.

Reading the file is as simple as reading a text file. The file has to be opened, a BufferedReader object is created to read the data in a line at a time.

Once a line of data has been read, we make sure that it's not null, or empty. If it is, we've hit the end of the file and there's no more data to read. If it isn't, we then use the split() method that's a member of Java's String object. This will split a string into an array of Strings using a delimiter that we give it.

The delimiter for a CSV file is a comma, of course. Once we've split() the string, we have all the element in an Array from which our Java programs can use the data. For this example, I just use a for loop to print out the data, but I could just as well sort on the values of one of the cells, or whatever I need to do with it in my program.

The Steps

  1. Open the file with a BufferedReader object to read it a line at a time.

  2. Check to see if we've got actual data to make sure we haven't finished the file.

  3. Split the line we read into an Array of String using String.split()

  4. Use our data.


The Program
// CSVRead.java
//Reads a Comma Separated Value file and prints its contents.

import java.io.*;
import java.util.Arrays;

public class CSVRead{

 public static void main(String[] arg) throws Exception {

  BufferedReader CSVFile = 
        new BufferedReader(new FileReader("Example.csv"));

  String dataRow = CSVFile.readLine(); // Read first line.
  // The while checks to see if the data is null. If 
  // it is, we've hit the end of the file. If not, 
  // process the data.

  while (dataRow != null){
   String[] dataArray = dataRow.split(",");
   for (String item:dataArray) { 
      System.out.print(item + "\t"); 
   }
   System.out.println(); // Print the data line.
   dataRow = CSVFile.readLine(); // Read next line of data.
  }
  // Close the file once all data has been read.
  CSVFile.close();

  // End the printout with a blank line.
  System.out.println();

 } //main()
} // CSVRead


Downloads

This program, and an example CSV file to use it with (a section of a spreadsheed I use to keep track of my integrated circuits) are available at my code archive.

Writing to CSV Files with Java

Writing to a CSV file is as simple as writing a text file. In this case, we write a comma between each field, and a newline at the end of each record.

Give it a try, starting with TextSave.java, modify it appropriately, then see what your favorite spreadsheet program thinks of the results.

Saturday, 15 September 2012

Java File Save and File Load: Objects

Jump to Reading Data from Files with Java>>


Saving Data to Files with Java


Saving objects to a file in Java has a few steps to it, but it's pretty easy. We open a file to write to, create a "stream" for putting objects into the file, write the objects to that stream to put them in the file, then close the stream and file when we're done.

To reiterate:

1. Open a file.

2. Open an object stream to the file.

3. Write the objects to that stream.

4. Close the stream and file.

1. Opening the File
To open a file for writing, we use a FileOutputStream object. When we construct the new FileOutputStream, we give it a file name to open. If the file name exists, it opens the existing file. Otherwise, it creates a new file. To keep things simple, we're not going to check for a file existing here, or anything like that.

Example:

FileOutputStream saveFile = new FileOutputStream("saveFile.sav");

2. Open an Object Stream
To write objects to the FileOutputStream, we create an ObjectOutputStream. We give it the FileOutputStream object we've set up when we construct the new ObjectOutputStream object.

Example:

ObjectOutputStream save = ObjectOutputStream(saveFile);

3. Write Objects
When we write objects to the ObjectOutputStream, they are sent out through it to the FileOutputStream and into the file.

Example:

save.writeObject(objectToSave);

4. Close Up
When we close the ObjectOutputStream, it'll also close our FileOutputStream for us, so this is just one step.

Example:

save.close();

Example Program:
import java.io.*;
import java.util.ArrayList;

public class SaveObjects{

  public static void main(String[] arg){

    // Create some data objects for us to save.
    boolean powerSwitch=true;
    int x=9, y=150, z= 675;
    String name="Galormadron", setting="on", plant="rutabaga";
    ArrayList stuff = new ArrayList();
    stuff.add("One");
    stuff.add("Two");
    stuff.add("Three");
    stuff.add("Four");
    stuff.add("Five");

    try{  // Catch errors in I/O if necessary.
      // Open a file to write to, named SavedObjects.sav.
      FileOutputStream saveFile=new FileOutputStream("SaveObj.sav");

      // Create an ObjectOutputStream to put objects into save file.
      ObjectOutputStream save = new ObjectOutputStream(saveFile);

      // Now we do the save.
      save.writeObject(powerSwitch);
      save.writeObject(x);
      save.writeObject(y);
      save.writeObject(z);
      save.writeObject(name);
      save.writeObject(setting);
      save.writeObject(plant);
      save.writeObject(stuff);

      // Close the file.
      save.close(); // This also closes saveFile.
    }
    catch(Exception exc){
      exc.printStackTrace(); // If there was an error, print the info.
    }
  }
}

Reading Data Files with Java


Now we need to know how to get data back from a file with Java. Since the data objects were stored using an ObjectOutputStream, they are saved in a way that makes them easy to read back using an ObjectInputStream.

There's one problem with ObjectImputStream, however. It doesn't return objects of the specific classes that they were originally. It just returns generic Objects. To get things back into their original class, we have to cast them into that type. Usually that means we need to know what their class was when they were written. It's possible to save class information along with the data, but in this case we just assume that we're reading back a file we have written, so we already know what class everything should be. I'll go into the details of reading other files in another article.

The steps are practically the same as for writing objects to a file:

1. Open a file.

2. Open an object stream from the file.

3. Read the objects to that stream.

4. Close the stream and file.

1. Opening the File
To open a file for reading, we use a FileInputStream object. When we construct the new FileIntputStream, we give it a file name to open. If the file name exists, it opens the existing file. Otherwise, we get an error which will print out a nastygram when we get to our catch statement. To keep things simple, we're not going to check for a file existing here.

Example:

FileInputStream saveFile = new FileInputStream("saveFile.sav");

2. Open an Object Stream
To read objects to the FileInputStream, we create an ObjectInputStream. We give it the FileInputStream object we've set up when we construct the new ObjectInputStream.

Example:

ObjectInputStream restore = ObjectInputStream(saveFile);

3. Read Objects
When we read objects from the ObjectInputStream, it gets then from the file.

Example:

Object obj = restore.readObject();

3 and a half. Cast Back to Class
Step 3. only restores a generic Object. If we know the original class, we should cast the Object back to its original class when we read it. If we had stored a String object, we'd read it something like this:

String name = (String) restore.readObject();

4. Close Up
When we close the ObjectInputStream, it'll also close our FileInputStream for us, so this is just one step.

Example:

restore.close();

Here's an example program to read back information saved by the first example program:
import java.io.*;
import java.util.ArrayList;

public class RestoreObjects{

 public static void main(String[] arg){

  // Create the data objects for us to restore.
  boolean powerSwitch=false;
  int x=0, y=0, z=0;
  String name="", setting="", plant="";
  ArrayList stuff = new ArrayList();
  
  // Wrap all in a try/catch block to trap I/O errors.
  try{
   // Open file to read from, named SavedObjects.sav.
   FileInputStream saveFile = new FileInputStream("SaveObj.sav");

   // Create an ObjectInputStream to get objects from save file.
   ObjectInputStream save = new ObjectInputStream(saveFile);

   // Now we do the restore.
   // readObject() returns a generic Object, we cast those back
   // into their original class type.
   // For primitive types, use the corresponding reference class.
   powerSwitch = (Boolean) save.readObject();
   x = (Integer) save.readObject();
   y = (Integer) save.readObject();
   z = (Integer) save.readObject();
   name = (String) save.readObject();
   setting = (String) save.readObject();
   plant = (String) save.readObject();
   stuff = (ArrayList) save.readObject();

   // Close the file.
   save.close(); // This also closes saveFile.
  }
  catch(Exception exc){
   exc.printStackTrace(); // If there was an error, print the info.
  }

  // Print the values, to see that they've been recovered.
  System.out.println("\nRestored Object Values:\n");
  System.out.println("\tpowerSwitch: " + powerSwitch);
  System.out.println("\tx=" + x + " y=" + y + " z=" + z);
  System.out.println("\tname: " + name);
  System.out.println("\tsetting: " + setting);
  System.out.println("\tplant: " + plant);
  System.out.println("\tContents of stuff: ");
  System.out.println("\t\t" + stuff);
  System.out.println();

  // All done.
 }
}

<<Return to How to Save to a File with Java

The example programs can be downloaded at:
Begin With Java Code Downloads

Friday, 14 September 2012

The Java Virtual Machine: Adapter Cables for Your Computer's Insides

One of the problems programmers have is that different computer systems all require different ways to program them. Each computer has its own way of doing graphics and sound, its own way to talk to the keyboard and mouse, and so on. So a program written for one system wouldn't run on another.

We used to have this problem with the hardware on computers, too. If you had a Windows computer and an Apple display, they wouldn't hook up to each other. Apple computers and PCs used different video connectors. The keyboards and mice also had different connectors. The same was true of Unix workstations. They had their own connectors for their monitors, keyboards, and so on, and the connectors for Sun workstations were different from those for HP workstations.

While the outsides of computers are pretty standard now--you can hook up a PC monitor to a Mac and vice versa, the same for USB keyboards and mice--the insides are still just as weird as the outsides used to be. Each computer maker has their own connection for programs that want to talk to graphics, sound, keyboard and mouse, and so on.

Back in the old days we could hook up hardware from different manufacturers sometimes using adapter cables. In other cases, we had adapters that not only connected from one connector to another, but also translated the electronic signals.

For programmers that want to write programs that run on lots of different computer systems, the Java Virtual Machine (JVM) is like a bundle of adapter cables between your program and the computer system it's running on. No matter what system you are on, the JVM makes it look the same to your program:



This is why it's called a "virtual" machine. Java provides a sort of make-believe computer that we can program for. Then the JVM makes other computer systems pretend to be that make-believe computer. So programs written for that make-believe computer will run on any computer that has the JVM on it.

In this way the JVM acts like a whole bunch of adapter cables. On a Windows system it takes the oddball connector from its graphics system and adapts it to your program so that you can use familiar graphics objects and their methods. Similarly, it adapts the sound from OS X to your program, so that you can play music or sound effects. It adapts the filesystem from Unix so that you can read and write files using the same objects and methods as you would use on Windows or OS X. And so on. The JVM adapts all the major parts of a computer to your program, so that you can wrote one program and have it run on all major computer systems, rather than having to spend your time writing it over and over for different systems.

The system isn't perfect. The biggest problem has to do with how programs are "packaged" on each of the different systems. Your program will be the same, but the way you get it to act like a native program on each system for the user varies. The program itself will be the same, but it may need a "helper" file or some other item on each host system to make it look just like a program written directly for that system.

This will typically not be a concern for you as a programmer when you're starting out. And packaging your programs for each operating systems is a lot less work than learning all the ins and outs of how to program each system (or even just one of the systems.)

The JVM is such a useful tool that languages other than Java are being written to take advantage of it. Jython, for example, is a version of the python language that's written to use the JVM. It lets you write python programs that will run on any system with a JVM on it. Groovy is another such language. There's a long list of languages that run on the JVM in addition to Java.

The Basic Program Skeleton

The basic skeleton of a Java application goes as follows:
public class YourProgramName{
  public static void main(String arg[]){

    Your Program Goes Here

  }
}

YourProgramName gets replaced by your actual program's name. The program must be stored in a file named YourProgramName.java

The actual code for your program goes in place of Your Program Goes Here.

More complicated programs have more to them than this. For example, you should have your own classes in their own files that contain most of your program logic if you are writing a long program. But this is the most direct and basic structure for a Java program.

The word arg can be whatever you choose to make it, by the way. If your program needs to get information from the system environment, just make sure that the name is the same as what you use in your program.