Friday, August 14, 2009

Java 3D Graphics Options

There are several approaches to doing 3-D graphics with Java. Unfortunately, there is no "standard" way. The core of Java does not include 3D graphics in the current versions (Java SE 5 and 6). The upcoming new version (SE 7) also does not, though it is intended to include a modular system that will download Java components that aren't already on a system as they are required. Chances are the major Java 3D APIs will take advantage of this.

Ways to Get 3-D Graphics in a Java Program:

1. Code It Yourself
You can write your own 3D graphics routines in standard Java. This avoids the need for those who run your programs to get add-ons to their Java to run your programs. It also means you'll really know what's going on in your 3D code.

However, this probably won't be an effective technique for you if you want to write programs with very sophisticated 3D in them, or need high performance.

2. JOGL
JOGL is a low-level set of APIs for accessing OpenGL on the system the program is running on. Runescape uses it. If you want to learn how to program 3-D the way most of the pros do it, and aren't afraid of having to learn all sorts of technical 3D graphics stuff to get there, then JOGL may be for you.

If you want to stick to a Java-like object oriented way of thinking, or don't want to delve too deeply into the underlying 3D graphics technology just to get a picture on-screen, then JOGL is probably not for you.

3. LWJGL
Another acronym, another low-level library like JOGL. LWJGL is oriented toward game development, including support for hardware like gamepads and controllers in addition to 3D graphics support. With respect to graphics, it has the same advantages and disadvantages as JOGL.

If I were going to start using the other capabilities of LWJGL right away, I'd start with it rather than JOGL. If I were focused on learning 3D graphics programming with OpenGL first, for example using the "Red Book" for OpenGL, I'd start with JOGL then move over to LWJGL if I felt it would be helpful.

4. Java3D
This is a high-level Java API that uses an object-oriented way of doing 3D graphics. It sticks with the same approach to doing things as the rest of Java. It lets you easily create 3D objects and set them up in scenes for display. If you're entirely new to 3D this is probably the place to start learning.

To use it, you need to install it on your system. Also, anyone who wants to run your Java3D programs will need to have it, too.

Java 3D binaries for different computer systems are available for download.

A good community site for further information on doing 3-D graphics with Java--no matter how you want to do them--is j3d.org.
StumbleUpon

Wednesday, July 1, 2009

Greenfoot Java Programming Book

There's a book on programming in Java with Greenfoot coming out soon.



You can see a preview at the book's site, along with resources for students and teachers.

This book isn't just for class use. Greenfoot is a great way to learn to use Java. You can learn the basics of programming with graphics and sound that are far easier to use than in standard Java. Greenfoot and BlueJ both illustrate basic concepts of Object Oriented programming in a way that makes them clearer than any other method I've seen. You can deal with objects as objects, see what their member methods and fields are, and use them outside the program itself.

So, if you're in a class or self-taught, I recommend using Greenfoot along with the online resources, and this book. The book can be completed in a short time and leave you ready to write your own programs with Greenfoot, or move on to using Java without Greenfoot if you wish.
StumbleUpon

Friday, June 19, 2009

Greenfoot Results

I've posted an entry on my general blog about the results I saw from a semester with Greenfoot.

While Greenfoot was not as smooth and easy to use for beginners as I could hope, it was still a very valuable tool for the class. Both it and BlueJ are excellent ways of being introduced to some of the basic concepts behind object-oriented programming. Objects, inheritance, members, etc. are all right there for you to see and interact with, which does a heck of a lot for making things clearer.

I'd like to see BlueJ's codepad come over into Greenfoot. The student I had in individual study using BlueJ and Objects First as a text got a lot out of the codepad.

I'm planning on spending more time with Greenfoot soon, to get a better idea of what could have been done to successfully implement ideas from class that didn't work out. We had our share of frustrations, but at this point I couldn't say whether they were the result of our shortcomings or opportunities for Greenfoot to improve.

Check out the post linked above. The student all got their games in a playable state and posted at the Greenfoot Gallery, which is a huge axchievement (I did not expect 100% success on that count!) They're linked, as are the students' development blogs.
StumbleUpon

Friday, February 27, 2009

Mini-Review: Learning Java by Patrick Niemeyer and Jonathan Knudsen

Once upon a time there was a neat little book called Java in a Nutshell. It described the Java language, feature by feature, and did a great job of teaching the language. It was targeted at people who were already programmers in some other language, but at the time there weren't a lot of people who'd consider using a new and somewhat narrowly-defined language like Java as a first programming language.

The first edition was pretty compact, true to the "Nutshell" name. Then Java grew, and the book grew with it. Now the current edition is huge, and that's even after they've moved out a lot of the examples and more detailed explanations to make room for everything else.

For those looking to learn Java, O' Reilly, the publishers of Java in a Nutshell, have a different book. It's appropriately named Learning Java. Like the original Java in a Nutshell, it's targeted at people who already know how to program. The title and cover design of this book don't suggest that, however, my feeling is they suggest that this is a beginner's book. Which it isn't, and the text of the book itself never says that it is.

The book is a good overview of Java for programmers learning Java. Beyond assuming that the reader is a programmer, it also assumes familiarity with object oriented language concepts. It briefly sketches them out, but if you're not already familiar with C++, Smalltalk, Objective-C, or some other object oriented language this book is not the place to start.

Learning Java is amazingly comprehensive. Java is a huge language with a lot of features. In some places the book has to cover things very briefly, in others it takes time to delve in a bit deeper. Those places where things are covered briefly often give short shrift to the subjects covered. Several related features will all get covered together, and instead of each one getting its own code example, several features will be demonstrated in a single piece of code that mashes them all together in one omnibus program. This makes understanding each individual subject much harder. There are also a lot of code snippets through the book in places where a short, complete program would provide a much better illustration than a few isolated lines of code.

In compensation for this, there are some code samples in the book that are excellent demonstrations of Java's power as a programming language. For example there are complete programs for a basic web server and a basic web browser in the book. These are both good demonstrations of Java features and a good jumping off point for the reader to start their own program. Threads are likewise covered with useful examples.

These examples make the book worth owning. It makes a great second or third book for someone learning Java. I wouldn't recommend it as the primary book for learning Java, however, only as an adjunct to some other book. My inclination would be to use this as a "third book." The first book should be a good teaching book for the level of the learner. The second book should be a strong, focused reference book for the areas of the language that are most important to that person's learning level. The third book should be a backfill with a broader range of examples and be a source of explanations with a different perspective from the first book to help out when the first book falls short of being clear for the learner.

This book is one of my favorites of those I own for that "third book" role. I draw examples from it for my classes, and look to it for supplementary explanations of features of Java. I've used it with students having trouble with concepts in other texts, having them work through the related portions of this book. It's been a great help that way.

Final Grade: 75%, C

Pros:
Some wonderful example programs.
Very comprehensive.
No fluff.

Cons:
Crowds too much into too few stand-alone example programs.
Does a poor job of teaching object oriented concepts.
Many sections are rushed.

Recommendation:
Get it to fill out your Java library, the excellent examples and good descri1ptions of areas of Java often not covered well elsewhere makes it worth having on the shelf. Don't buy it as a primary learning text, however, no matter what your level as a programmer.
StumbleUpon

Friday, February 20, 2009

Rotating an Image with Java

In an earlier lesson we learned to load an image file into Java and display it. We also scaled the image in the program given in that lesson. Now we're going to get just a tiny bit more sophisticated, and rotate the image, as promised in the lesson introducing Java2D.

The basic graphics functions of Java allow for positioning an image in a window and scaling that image. But that's about all. If you want to rotate the image, skew it (make it look like it's leaning over) or do other things to the image you display you need to use Java2D.

What we'll do in this program is load the image as before. But before the image is drawn we will create a Java2D version of our graphics object that we're drawing to. Then we'll rotate that graphics object and draw the image. The rotation results in everything that gets drawn to the graphics area being rotated by the amount specified.

The program uses the same image of Duke as the previous one. It needs to be in the same directory as your program.

Here's the program. More discussion of the program follows the listing.
// Import the basic graphics classes.
import java.awt.*;
import javax.swing.*;
/**
* Simple program that loads, rotates and displays an image.
* Uses the file Duke_Blocks.gif, which should be in
* the same directory.
*
* @author MAG
* @version 20Feb2009
*/

public class RotateImage extends JPanel{

// Declare an Image object for us to use.
Image image;

// Create a constructor method
public RotateImage(){
super();
// Load an image to play with.
image = Toolkit.getDefaultToolkit().getImage("Duke_Blocks.gif");
}

public void paintComponent(Graphics g){
Graphics2D g2d=(Graphics2D)g; // Create a Java2D version of g.
g2d.translate(170, 0); // Translate the center of our coordinates.
g2d.rotate(1); // Rotate the image by 1 radian.
g2d.drawImage(image, 0, 0, 200, 200, this);
}

public static void main(String arg[]){
JFrame frame = new JFrame("RotateImage");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600,400);

RotateImage panel = new RotateImage();
frame.setContentPane(panel);
frame.setVisible(true);
}
}

Most of this program is the same as our previous one. There are a couple of significant changes, however.

One is the following line:
Graphics2D g2d=(Graphics2D)g;
In this line we're doing what's known as a "cast". We're declaring a new Graphics2D object, naming it g2d, then setting its value to our present Graphics object, g. But since g is a Graphics object, and not a Graphics2D object, we're telling it to treat g as a Graphics2D object for the purposes of this assignment. We can get away with doing this because Graphics2D is a subclass of Graphics, which makes the two classes compatible enough to allow the cast to be successful.

By doing this, we "magically" make all the Graphics2D functions available for drawing to our window.

What we want to do is rotate our image. Since we don't want to have the image go outside our graphics area when we rotate it, I've moved our "point of origin" of our graphics area using
g2d.translate(170, 0);
This moves the center point around which the drawing area is rotated from the upper left corner of the window's display area to a point 170 pixels to the right of that.

Then we use the rotate() method of our Graphics2D object, which will cause everything drawn into it to be rotated:
g2d.rotate(1);
The amount we're rotating is 1 radian, or about 57 degrees, noted by the 1 inside the parentheses.

Then we use the drawImage method of our Graphics2D object to actually draw the image into our display area.

Experiment with different values for the rotate() method to see rotation at different angles. If you lose part of the image off the edge of the window, try to use different offsets in the drawImage() method to change the location within the window at which the image gets drawn.

This is a fairly simple method for rotating an image in Java. It has some value for creating static images that are rotated, but for something like sprites in a game it's not very useful. The best method for that would be to create rotated images in a graphics program, not in your Java program. It's possible to rotate your images in Java, but it gets complicated because you have to worry about a lot of things that your graphics program does for you, like the area your new image will fill relative to the original, the background of the image, and so on.

Once you have image files of your sprite in all its possible rotated angles, load all these images to different Image object in a Java program (or better yet, an Image array or Collection), and change between them to show the image rotating.
StumbleUpon

Saturday, February 14, 2009

Better 2D Graphics: Java2D

In our last program we loaded and displayed an image using Java. Not only that, but we scaled it to be a specific size. We did this using the Image class from the java.awt package.

Unfortunately, this pretty well covers the abilities of the Image class. But there's so much more that we'd like to do with images in our programs, especially if we're writing games. Fortunately, there's more that Java can do with images thanks to Java2D.

If you go to the Java API you won't see a specific package called something like java.java2d or javax.swing.java2d. "Java2D" is a whole bunch of packages and classes spread through Java's libraries of stuff. The java.awt.image package is part of Java2D, as is the java.awt.Graphics2D class inside the java.awt package. For a list of all the scattered components of Java that are part of Java2D, have a look at the Java2D API Specification.

Like so much of Java, the presentation of Java2D is confusing. It's made to sound like a single thing when it's a bunch of interrelated things worked into Java. Fortunately, like many such problems in understanding Java, it's only a problem of how the language is presented, not a problem with the language itself. Once you get to working with the elements of Java2D, you find that they're fairly naturally positioned in the places you would expect them in Java by their function. Which is how they got spread out in the first place (that and some history--it would have been even more natural to have there be one Graphics class that does everything, rather than a Graphics and Graphics2D class.)

Also, it's very easy to take items that are non-Java2D classes and use them with Java2D. Usually it's nothing worse than "casting" them as Java2D objects. That means you basically tell Java "pretend this object is the right sort of thing" in a way that works.

So have a look at some info on Java2D, and if it looks confusing, remember it's not you that's the problem. Sun does an amazing job of presenting great things in awful ways by trying to say way too much to too many different audiences at once. And they like to start in the middle of the story.

The Java2D tutorials do a decent job of showing things off without a lot of mind-numbing prose (well, not too much, anyway.)

Next I'll post a short, simple program we can use that rotates our images.
StumbleUpon

Monday, January 26, 2009

Loading and Displaying an Image in Java

Here's a common task--loading an image file and displaying it in a window.

I'll be using this program as a basis for further two dimensional graphics exercises, so give it a try and play around with it.

First, we need to get a picture to use. I use a picture of Duke, the Java mascot, from https://duke.dev.java.net/images/web/Duke_Blocks.gif

If you want to run the program as I present it, download the image and save it into the same directory that yor java program will be in. If you want to use your own image, replace the file name Duke_Blocks.gif with the name of your image file, and make sure the image is in the same directory as your java program.

The only somewhat tricky part is that we're using a Toolkit method to get the image. Take a look at the Java API reference to learn more about the Toolkit. (The Toolkit object is part of the java.awt package. So select "java.awt" in the top left frame of the API reference webpage to make finding Toolkit in the lower left frame easier.)

In this program, we scale and position the image in our window. In future programs, we'll convert the image to a Java2D object (which is really easy) so that we can do other things, like rotate it and use it as a sprite.

Here's the program:
/* ShowImage.java

  This program loads and displays an image from a file.

  mag-13May2008
  updated 20Feb2009 by mag to incorporate suggestions
  by mazing and iofthestorm on digg.
*/

// Import the basic graphics classes.
import java.awt.*;
import javax.swing.*;

public class ShowImage extends JPanel{
  Image image; // Declare a name for our Image object.

// Create a constructor method
  public ShowImage(){
   super();
   // Load an image file into our Image object.
   // This file has to be in the same
   // directory as ShowImage.class.
   image = Toolkit.getDefaultToolkit().getImage("Duke_Blocks.gif");
  }

// The following methods are instance methods.

/* Create a paintComponent() method to override the one in
JPanel.
This is where the drawing happens.
We don't have to call it in our program, it gets called
automatically whenever the panel needs to be redrawn,
like when it it made visible or moved or whatever.
*/
  public void paintComponent(Graphics g){

   // Draw our Image object.
   g.drawImage(image,50,10,200,200, this); // at location 50,10
     // 200 wide and high
  }

  public static void main(String arg[]){
   JFrame frame = new JFrame("ShowImage");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.setSize(600,400);

   ShowImage panel = new ShowImage();
   frame.setContentPane(panel);
   frame.setVisible(true);
  }
}
StumbleUpon

Tuesday, January 13, 2009

Listeners: Can Java Hear You?

In the program given in Simple Mouse Interaction in Java we used a Listener to connect our program to the mouse. We were able to use the Listener to find out when and where the mouse had been clicked within our program's window. We used this information to draw lines in the window, in a similar fashion to our earlier programs but controlled by the mouse, rather than from specific drawing instructions in the program that do the same thing every time you run the program.

By implementing the MouseListener interface, we were able to talk to the mouse very easily. However, a MouseListener is just one of the many types of Listener available in Java.

What Sort of Listener Are You?


If we tried to implement a full graphical interface in a program by using MouseListener, we'd have a lot of work to do. We'd have to draw all the buttons using drawing instructions in our program, then wait for mouse clicks. Once we got a click on something we'd have to figure out what had been clicked on by the location of the click in our window. Then we'd have to redraw the button (or slider, or whatever) to show that it had been clicked. Then we'd have to continue responding to the mouse by figuring out what the user is doing (clicking and releasing, clicking and dragging, or what) and make our program and the picture on the screen respond appropriately.

Whew! What a lot of work that would be! If we had to do that it'd almost be enough to drive you back to the command line. (Once upon a time you did have to do all that, believe it or not. Thank goodness those days are gone.)

Fortunately, Java has a number of different types of Listener suited for different tasks that take care of the complexity for you, and let your program do what you want it to do without you having to spell out every little detail. There are listeners for buttons, sliders and other controls such as trees, lists, focus changes, and so on. You can also write your own Listeners, so that you can create a new type of control and only ever have to deal with the inner complexities of how it works once.

What is a Listener?

A Listener is a connection between your program and something that creates an Event. An Event is a communication from a device on the computer or a program to something outside itself on the computer, like another program or device (through a program associated with that device, like its device driver.) In the case of our mouse program, the Listener is the connection between the mouse's button and our program. Whenever the left button is clicked, an Event is generated that contains what happened (a left-click) and the location in our window where it happened.

If the click happens outside our program's window, an Event is generated, but our program isn't included in the recipients of the message. If our program doesn't have a Listener, the mouse click Event gets passed to our program but is ignored.

If we have a Listener appropriate to an Event that's passed to our program, then something happens with it. So we have to create a Listener, tell our program to add it to its list of Listeners (which also tells the program what kind of events it's listening for.) Then our program will tell that Listener whenever one of those events happens, and pass along the details.

A MouseListener is a very generalized sort of Listener. An ActionListener, however, can be set up to listen for a specific event, like a click on a specific button. Take a look in the Java API at ActionListener. By associating an ActionListener with a specific button, you can hear only about when that button is clicked, and know that that's precisely what happened. That ActionListener won't hear about clicks elsewhere, you don't need to check the location of the click, and it won't tell you about anything else you don't want to hear about.

That saves you all the trouble that I talked about above. You can set up your ActionListener to just exeecute the part of your code you want it to run when someone clicks the button. Or slides the slider, or whatever. No fuss, no muss.

I'll be posting a sample program soon, until then have a look at the Sun Java Tutorials on using buttons and other controls from Swing (Java's best set of graphical user interface objects.)
StumbleUpon