Valid
	XHTML 1.1! Valid CSS!
Created 2005-06-18 Modified 2009-04-12
Chelton Evans

Java home

Basics
Callbacks
JList
Process Command Line Arguments
Gui Get an Integer
Callback for a Group of Buttons
Runtime Binding
Files
    File Writing
    File Reading
    RandomAccessFile
    Downloading Files from the Web
GUI
    Application and Applet
    JTextPane
    JMenuBar
    JComboBox
    GridLayout
Threads
Installing Java on Linux Box
javadoc
String Serialization
Linked List  
Java3D(deprecated)
OpenGL

Basics

Compile Java.
javac <class-name>.java
Compiling with assert
javac -source 1.4 -classpath . *.java
Run java with
java <class-name>
Including the class path so Java can find the source files
javac -classpath . Counter.java Counter2.java CounterTest.java
To see the top error messages
javac <class-name>.java 2>&1 | head

Console reading
Get a string
import java.io.*;
...
    BufferedReader br = new BufferedReader( new InputStreamReader(System.in));
    String s = br.readLine()
   
Menu choice
System.out.println(" 1: add elements to list and print ");
System.out.println(" 2: add some elements in order to print ");
BufferedReader in=new BufferedReader(
  new InputStreamReader(System.in));
int ch;
try
  { ch = in.read(); }
catch (IOException e)
  { System.out.println("error: unable to read selection."); return; }
switch (ch)
{
  case '1': ...
    break;
  default: ...
}
Read an integer
BufferedReader stdin = new BufferedReader(
  new InputStreamReader(System.in) );
String msg = stdin.readLine();
int elem = Integer.parseInt(msg);

Compare strings   String("a").equals("a")

Perform a cast.
void castit(Object x)
{
  // If x is null this code will not be executed.
  if (x instanceof Address)
  {
    Address a = (Address)x;
    System.out.println(a);
  }
}

arrays - create one and then fill it
players = new Player[this.nPlayers];
for (int i=0; i<this.nPlayers; ++i)
  players[i] = new Player();

Callbacks

These are functions which are called after an event is triggered. In Java there is a tendency to use callbacks in unclean ways. Through inheritance, handling of multiple callbacks with the one handler, a multitude of callback mechanisms ... There are arguments for efficiency but now with todays computers there should be no need for multiple callbacks to be handled by the one handler.

Here is a technique that directly maps the callback to a function. Put this within your class. This furthers OO design by making your program neat and generic.

In this example I avoided inheriting ActionListener by creating an temporary class - I do not know the technical name for this. If I wished to design a gui with many buttons they can all be linked to individual function calls.

Notice that both import statements are necessary, I do not know why only that its another Java bug.

import java.awt.*;
import java.awt.event.*;
...
  JTextField enterFileName;
...
  // The function which is called back and local to the class.
  public void fileRead(String s)
...

    enterFileName.addActionListener
    (
      new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          String s = e.getActionCommand();
          fileRead(s);
        }
      }
    );

See ThreeButtons.java - Inheritance for callbacks with inheritance and the old style of handling callbacks. What I believe is the better way - less error prone, simpler and the action is exactly matched with the action code. See ThreeButtons2.java - direct. What I like most is that the direct method is more object orientated - the actions in the inheritance are often all implemented in the handler and not as separate function calls as with the direct way.

JList

Vector v3 = new Vector(); ...  // Populate with strings
JList xList = new JList(v3); // Initialize 
wind.add(xList,BorderLayout.CENTER);  // Add to window
int indx = xList.getSelectedIndex();  // Get the users choice

// Add the callback
xList.addListSelectionListener
(
  new ListSelectionListener ()
  {
    public void valueChanged(ListSelectionEvent e)
    { transSelectInstrument(); }
  }
);

GUI

The idea of the gui is its best to allow the user to resize or change everything and still have it looking good. This means avoiding certain classes and using JPane components. For example JTextArea with JScrollPane does not resize properly, so use JTextPane instead.

Application and Applet

An obvious question when programming Java is that if we write an application how can the application be written the same in an applet. To be more specific how can we code so that the application and applet use the same code.

There are going to be some restrictions as the applet has less file access rights, but these can be granted.

Sticking to Swing's JFrame and JApplet the same Gui code can be used. Indeed if everything is in the default constructor then the only changes that need to be made are inheriting a JApplet instead of JFrame. In applets exclude some gui code.

For the applet Java documentation recommends overloading init(). eg placing thread code in here as the object has already been constructed. Alot of people take this recommendation literally and put code that should be in the default constructor and place it here too. Since Java already provides a default init() function that does nothing, you can even get away with the thread calls also being in the constructor - even though an object is not fully constructed starting a runnable thread at the end of the constructor is ok because you have already initialized everything this code is always going to work.

extends JFrame extends JApplet
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
setSize(400,400);
setVisible(true);
do not set the size or visibility as these are done in the browser

To include Java in a HTML document use can use the applet tag. Class GUIExam2 has been compiled to GUIExam2.class

<applet code="GUIExam2.class" height="300" width="300">
</applet>

JTextPane

JTextPane textpane = new JTextPane();
...
//Append
String msg = ...
textPane.setText( textPane.getText() + mgs );

Just in case you need JTextArea.

JTextArea infoDisp;
JScrollPane infoDispScroll;
...

infoDisp = new JTextArea(10,20);
infoDispScroll = new JScrollPane
( 
  infoDisp,
  JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
  JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS
);

JComboBox

JComboBox(Object[] items) 
JComboBox(Vector items) 
  String combstr[] = { "A","B","C" };
  JComboBox comb = new JComboBox(combstr);
void addActionListener(ActionListener l) 
int getSelectedIndex() 
Object getSelectedItem()

GridLayout

// one row, two columns.
JPanel wind2 = new JPanel(new GridLayout(1,2));
JButton b1 = new JButton("Clear");
wind2.add(b1);
...
setContentPane(wind2);

GridLayout() is one column per component.

JMenuBar

JMenuBar menuBar = new JMenuBar();

JMenu info = new JMenu("Information");
    
// Alt+I to select this menu
info.setMnemonic(KeyEvent.VK_I);      
menuBar.add(info);

info.add(infoCompanyDetails);

JMenuItem infoCompanyDetails = new 
  JMenuItem("Company Details");
infoCompanyDetails.setMnemonic(KeyEvent.VK_D);

// Add the callback
infoCompanyDetails.addActionListener
(
  new ActionListener ()
  {
    public void actionPerformed(ActionEvent e)
      { infoCompanyDetailsAction(); }
  }
);

ButtonGroup

Setting one button turns of all the others.

JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(buttonPanel,BoxLayout.X_AXIS));
ButtonGroup buttonGroup = new ButtonGroup();
String[] options = { "a","b","c" };
JRadioButton[] radioButton = new JRadioButton[options.length];
for (int i=0; i<options.length; ++i)
{
  radioButton[i] = new JRadioButton(options[i]);
  buttonPanel.add(radioButton[i]);
  buttonGroup.add(radioButton[i]);

  //shiprb[i].setActionCommand(shippingOptions[i]);
}

//    rb = shiprb[shipChoiceState];
//    rb.setSelected(true);

You would think that turning on a button would be simple with Java but a toggle is anything but simple. Here is code to turn on the button if it is not selected already.

if (paymentButtonInvisible.isSelected()==false)
  paymentButtonInvisible.doClick();

For the radio buttons to have no effect there is no one way to turn them off so Java's doc recommends having an invisible button for the job.

Process Command Line Arguments

  String commandlineGet(String targ, String[] args)
  {
    String s = "";
    for (int i=0; i<args.length; ++i)
    {
      if( args[i].startsWith(targ) )
        s = args[i].substring(targ.length());
    }

    return s;
  }
  

  boolean commandlineProcess( String[] args )
  {
    boolean filenamefound = false;
    
    dataFileName = commandlineGet("data=",args);
    if (dataFileName != "")
      filenamefound = true;

    ...

Gui Get an Integer

class GuiGetInt
{
  public static int get(String s)
  {
    try
    {
      String s2 = 
        JOptionPane.showInputDialog(s);
      
      int k = Integer.parseInt(s2);
      return k;
    }
    catch (Exception e)
    {
      return -1;
    }
  }
}

Code

Gui2.java  

Callback for a Group of Buttons

Not recommended, old style of callbacks suffers from non-uniqueness problem. Instead see Callbacks.

class Keypad extends JPanel implements ActionListener
{
...

  Keypad(...
  
    for(int i = 9; i >= 0; i--)
    {
      p.add(b = new Button("" + (char)('0' + i)));
      b.addActionListener(this);
    }
  ...

  public void actionPerformed(ActionEvent e)  
  {
    String nm = e.getActionCommand();
    //**** READ BELOW
}

The string which the button was given is returned in nm if that button was pressed. Therefore test for that string.

The idea is a group of buttons are treaded as on and all calls or presses of these buttons go through the actionPerformed function.

Runtime Binding

Shipping s = null;
try
{
   Class x = Class.forName(file);
   s = (Shipping) x.newInstance();
}
catch( Exception e)
{
   s = null;
}

file   is the name of the file without the .class extension. You could make the code cleaner.

Shipping s = null;
try
{
   s = (Shipping)(Class.forName(file).newInstance());
}
catch( Exception e)
{
   s = null;
}

Files

File Writing

   // Create the file so it exists and can be written to.
   FileOutputStream f = new FileOutputStream(errorFileName);
   f.close();

Example of appending to a file.

  /** Append error message to the error file */
  public boolean write(String errorMessage)
  {
    try
    {
      PrintWriter p =
        new PrintWriter
        (
          new FileOutputStream(errorFileName,true)
        );

      p.println(errorMessage);

      p.close();
    }
    catch(Exception e)
    {
      return false;
    }

    return true;
  }

File Reading

import java.io.*;

public class ReadText
{
  public static void main( String f[] )
  {
    try
    {
      BufferedReader buf = new BufferedReader( new FileReader(f[0]) );
      
      for ( String line = buf.readLine(); line!=null; line=buf.readLine() )
        System.out.println(line);
     
    }
    catch( FileNotFoundException e )
    {
      System.out.println("Error:  file not found.");
    }
    catch( IOException ioe )
    {
      System.out.println("Error: IO  " + ioe );
    }
  }
}

Java has a File class for accessing the files directory structure. It can do heaps. Here is a simple example of reading a file FileTest.java.

RandomAccessFile

reading and writing to the file increment the file pointer. Here is a state diagram of the following program.

It appears that the size of an integer is 4. * is the current file pointer.

  1  2  3
         *    raf.writeInt(i);
    *         raf.seek(raf.getFilePointer()-4*2);
    x=2       int x=raf.readInt();
       *
    x=10
    *         raf.seek(raf.getFilePointer()-4*1);
    12        raf.writeInt(x);
       *
 *            raf.seek(0);
import java.io.*;

public class Q12
{

  public static void main(String[] args)
  {
    try
    {
      RandomAccessFile raf = 
        new RandomAccessFile("test.dat","rw");
      for (int i=1; i<=3; ++i)
        raf.writeInt(i);

      raf.seek(raf.getFilePointer()-4*2);
      int x=raf.readInt();
      x = x + 10;

      raf.seek(raf.getFilePointer()-4*1);
      raf.writeInt(x);

      raf.seek(0);
      for (int i=1; i<=3; ++i)
        System.out.println(" " + raf.readInt());

    }
    catch (FileNotFoundException fnfe)
    {
      System.out.println("error: file not found");
      return;
    }
    catch (IOException ioe)
    {
      System.out.println("error " + ioe);
    }
  }
}

Downloading Files from the Web

Here is a utility program to download a public file from the web and rename it. Also you can combine this with scripting to download multiple files.

code/DownloadFile.java

Threads

Java has some neat ways of using threads. To kill a thread simply set its reference to null. When writing a thread generally have it do an action till the end. Either its got to do a finite task or it goes on forever. Generally do not pause a thread rather kill it and if you need to start again start a new thread in the new context.

class W extends Thread ...
W w ...
w.start()

 or 
class W2 implements Runnable 
{
  void run() { ...

new W2().start()

For example see Counter.java Counter2.java CounterTest

synchronized code has implicit mutexes within the object so two or more threads do not access the one object at the same time.

The producer consumer problem. code/StackDemo.java, StackUser.java

Installing Java on Linux Box

Installed Java plug-in for Mozilla
Downloaded self extracting file
Downloaded it, changed its permission
in /usr/java directory
chmod a+x jre-1_5_0_01-linux-i586.bin
./jre-1_5_0_01-linux-i586.bin

Found where Mozilla lived. But used their
 general directory.

/usr/lib/mozilla/plugins

ln -s /usr/java/jre1.5.0_01/plugin/i386/ns7/libjavaplugin_oji.so .

There was another version of the java library but this crashed
  the browser.

Enabled the browser to run Java by selecting Preferences + Advanced and checking the Enable Java box.

For java itself I believe that I downloaded and compiled it, then set the path to include the directory where javac lived in my path.

Linked List

Traditional exercise creating, accessing a linked list of intergers. A linked list is a list of connected nodes, each link has a pointer to the next link and a data element. List.java   ListTest.java   ListNode.java  

Serialize with Strings

Generally serialize with strings. ie write the object to and from a text string. Java provides toString() for writing out the object and split for parsing and reading it back in.

public class SnakeLadder
{

  public int start;
  public int finish;

  ...

  public String toString()
    { return "" + start + " " + finish; }

  public boolean readFrom(String s)
  {
    try
    {  
      String line = s.trim();

      String[] result = line.split("\\s");
      assert( result.length == 2 );
      this.start = Integer.parseInt(result[0]);
      this.finish = Integer.parseInt(result[1]);

System.out.println("line=" + line);

    }
    catch (Exception e)
      { return false; }

    return true;
  }

  public String toString()
    { return "" + start + " " + finish; }

}

javadoc

tags
@author pleasekillinventorofthistagforuselesness
{@ link#<signature> [display text]}
{@ link <classname>#<signature>[...]}
@see <a href="spec.html#section">text</a>

javadoc - The Java API Documentation Generator

OpenGL

Java OpenGL
Rotating Gears
TODO - run. Examples. Web page.