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
Compile Java. javac <class-name>.java. I use a makefile.
Run java with java <class-name>
import java.io.*;
...
BufferedReader br = new BufferedReader( new InputStreamReader(System.in));
String s = br.readLine()
...
System.out.println("hat");
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);
}
}
Whenever you program Java you need their API documentation. Downloaded Sun's Java doc http://java.sun.com/j2se/1.3/docs.html
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.
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(); }
}
);
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.
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 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(Object[] items) JComboBox(Vector items)
String combstr[] = { "A","B","C" };
JComboBox comb = new JComboBox(combstr);
void addActionListener(ActionListener l) int getSelectedIndex() Object getSelectedItem()
// 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 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(); }
}
);
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.
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;
...
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;
}
}
}
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.
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;
}
// 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;
}
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.
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);
}
}
}
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.
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()
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
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.