GraphReader
/**************************************************************************/
/* Graph Reader V2.0 (C) Ju Li (liju99@mit.edu) - Wed Sep 8 1999 */
/* http://mmm.mit.edu/~liju99/Archive/NetApp/JavaScript/Reader/reader.htm */
/* Includes: reader.htm reader.java -> reader.class example.gif test.gif */
/* Usage: % javac -O -ver 1.1.3 reader.java; netscape reader.html & */
/**************************************************************************/
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class reader extends Applet
implements ActionListener, KeyListener, MouseListener, ItemListener
{
// toy list
String graph_file;
Image graph;
MediaTracker tracker;
TextField T_Anchor;
// TextField T_Command;
Button B_Anchor,B_Print_Matlab,B_Print_Latex,B_Print_HTML;
Checkbox C_Show_Saved;
Graphics applet_graphics;
boolean show_saved = true;
// (basex,basey) is the upper-left corner of the graph
int basex=10,basey=10;
// default graph properties
int graph_width=510,graph_height=440;
// cover the floor with this color in case graph is transparent and thin
float graph_background_R=(float)1,graph_background_G=(float)1,
graph_background_B=(float)1;
Color graph_background_color;
// default graph font for messaging and labelling
String graph_fontname = "TimesRoman";
final static int GRAPH_FONTSTYLE = Font.ITALIC;
int graph_fontsize = 12;
Font graph_font;
FontMetrics graph_fontmetrics;
// default graph pointer properties
int pointer_size=2,hollow_pointer_size_added=1,hollow_pointer_size;
float pointer_R=(float)0,pointer_G=(float)0,pointer_B=(float)0;
Color pointer_color;
final static int POINTER_STEPSIZE_CONTORL=10, POINTER_STEPSIZE_SHIFT=10,
POINTER_STEPSIZE_ALT=5, POINTER_STEPSIZE_META=5;
// (curx,cury) is the screen position of the pointer
int curx=-10000,cury=-10000;
// anchor screen coordinates and corresponding values
int nanchor=0,anchorx[]=new int[3],anchory[]=new int[3];
double fanchorx[]=new double[3],fanchory[]=new double[3];
String anchorname[] = {"Set 1st anchor (x1 y1):",
"Set 2nd anchor (x2 y2):",
"Set 3rd anchor (x3 y3):",
"Press again to reset"};
// floating-point tolerable tiny and relative error
final static double tolerable_tiny = 1E-14;
final static double tolerable_relative_error = 1E-4;
// (ax,ay) is how much a unit A vector corresponds on screen
// (bx,by) is how much a unit B vector corresponds on screen
double ax,ay,bx,by,det;
// saved data stack
int nsaved = 0;
final static int MAXSAVE = 512;
int savex[]=new int[MAXSAVE], savey[]=new int[MAXSAVE];
double fcurx,fcury,fsavex[]=new double[MAXSAVE],
fsavey[]=new double[MAXSAVE];
// global status bar messaging
String status_mesg;
static boolean already_been = false;
public void init()
{
int i;
String arg;
tracker = new MediaTracker(this);
graph_file = getParameter("graph_file");
if ( graph_file.startsWith("http:") ||
graph_file.startsWith("HTTP:") ) // remote
graph = getImage(getDocumentBase(), graph_file);
else // local
graph = getToolkit().getImage(graph_file);
status_mesg = "Loading " + graph_file + "...";
showStatus(status_mesg);
System.out.println(); System.out.println();
System.out.println(status_mesg);
tracker.addImage(graph,0); // graph ID = 0
setLayout(new BorderLayout());
Panel south = new Panel();
add ("South", south);
south.setLayout(new FlowLayout());
south.add(B_Anchor = new Button(anchorname[nanchor]));
// Buttons feel Action, inform applet before & after themselves
B_Anchor.addActionListener(this);
south.add(T_Anchor = new TextField("0. 0. "));
// TextFields feel Key, inform applet before & after themselves
T_Anchor.addKeyListener(this);
// T_Command = new TextField(0);
// south.add(T_Command);
// T_Command.addKeyListener(this);
south.add(B_Print_Matlab = new Button("MLB"));
B_Print_Matlab.addActionListener(this);
south.add(B_Print_Latex = new Button("LTX"));
B_Print_Latex.addActionListener(this);
south.add(B_Print_HTML = new Button("HTML"));
B_Print_HTML.addActionListener(this);
south.add(C_Show_Saved = new Checkbox("Show saved",show_saved));
// Checkbox feels Item, inform applet before & after themselves
C_Show_Saved.addItemListener(this);
// the applet itself feels Mouse
addMouseListener(this);
// if we comment out the next line and uncomment all
// lines involving T_Command, we get a vi prototype
addKeyListener(this);
// disable all the gadgets - very narrow event path
B_Anchor.setEnabled(false);
T_Anchor.setEnabled(false);
// T_Command.setEnabled(false);
B_Print_Matlab.setEnabled(false);
B_Print_Latex.setEnabled(false);
B_Print_HTML.setEnabled(false);
C_Show_Saved.setEnabled(false);
arg = getParameter("basex");
if (arg != null) basex = Integer.parseInt(arg);
arg = getParameter("basey");
if (arg != null) basey = Integer.parseInt(arg);
basex += getBounds().x;
basey += getBounds().y;
arg = getParameter("graph_width");
if (arg != null) graph_width = Integer.parseInt(arg);
arg = getParameter("graph_height");
if (arg != null) graph_height = Integer.parseInt(arg);
arg = getParameter("pointer_size");
if (arg != null) pointer_size = Integer.parseInt(arg);
hollow_pointer_size = pointer_size + hollow_pointer_size_added;
arg = getParameter("pointer_R");
if (arg != null) pointer_R = (new Float(arg)).floatValue();
arg = getParameter("pointer_G");
if (arg != null) pointer_G = (new Float(arg)).floatValue();
arg = getParameter("pointer_B");
if (arg != null) pointer_B = (new Float(arg)).floatValue();
pointer_color = new Color(pointer_R,pointer_G,pointer_B);
arg = getParameter("graph_fontsize");
if (arg != null) graph_fontsize = Integer.parseInt(arg);
arg = getParameter("graph_fontname");
if (arg != null) graph_fontname = arg;
graph_font = new Font(graph_fontname, GRAPH_FONTSTYLE,
graph_fontsize);
arg = getParameter("graph_background_R");
if (arg != null) graph_background_R = (new Float(arg)).floatValue();
arg = getParameter("graph_background_G");
if (arg != null) graph_background_G = (new Float(arg)).floatValue();
arg = getParameter("graph_background_B");
if (arg != null) graph_background_B = (new Float(arg)).floatValue();
graph_background_color = new Color(graph_background_R,
graph_background_G,
graph_background_B);
applet_graphics = getGraphics();
graph_fontmetrics = applet_graphics.getFontMetrics(graph_font);
try
{
tracker.waitForID(0);
status_mesg =
"Click in the graph. You will see your pointer.";
}
catch ( Exception e )
{
status_mesg = "Exception: " + e.getMessage();
System.out.println(status_mesg);
}
showStatus(status_mesg);
return;
} // end init()
public void draw_pointer (Graphics g, int x, int y, int size)
{ // draw pointer centered at x,y
int px[] = {x+size, x, x-size, x };
int py[] = {y, y+size, y, y-size};
g.fillPolygon (px, py, 4);
return;
} // end draw_pointer()
public void draw_hollow_pointer (Graphics g, int x, int y, int size)
{
int px[] = {x+size, x, x-size, x };
int py[] = {y, y+size, y, y-size};
g.drawPolygon (px, py, 4);
return;
} // end draw_hollow_pointer()
public boolean in_graph (int x, int y)
{
return ( (x >= basex) &&
(y >= basey) &&
(x <= basex+graph_width-1) &&
(y <= basey+graph_height-1) );
} // end in_graph()
public void xorpaint_cur_pointer (Graphics g)
{
// XOR overlap paint mode:
g.setColor (graph_background_color);
g.setXORMode (pointer_color);
// c -> graph_background_color (+) pointer_color (+) c
if (in_graph(curx,cury))
draw_pointer (g, curx, cury, pointer_size);
return;
} // end xorpaint_cur_pointer()
public void xorpaint_saved (Graphics g, int start, int finish)
{
int i;
String data_index;
g.setColor (graph_background_color);
g.setXORMode (pointer_color);
// c -> graph_background_color (+) pointer_color (+) c
for (i=start; i<=finish; i++)
if (in_graph(savex[i],savey[i]))
{
draw_hollow_pointer (g, savex[i], savey[i],
hollow_pointer_size);
g.setFont(graph_font);
data_index = Integer.toString(i+1);
// drawString origin is lower-left corner:
g.drawString (data_index, savex[i] -
graph_fontmetrics.stringWidth(data_index)/2,
savey[i] + graph_fontmetrics.getHeight() +
hollow_pointer_size);
}
return;
} // end xorpaint_saved()
public void update (Graphics g)
{
// update(), if not overridden, will
// 1) clear g 2) set colors 3) call paint(g).
// The "clear g" part is the reason screen flashes.
paint (g);
showStatus(status_mesg);
} // end update()
public void paint (Graphics g)
{ // pretend to always start all over
g.setColor(graph_background_color);
g.setPaintMode();
// clean whatever marks one has left
g.fillRect(basex, basey, graph_width, graph_height);
if (tracker.isErrorID(0))
{ // tracks progress of loading the graph
status_mesg = "Bad image. Check by clicking the top-most link.";
showStatus(status_mesg);
g.setFont(graph_font);
g.setXORMode(pointer_color);
g.drawString(status_mesg, basex +
(graph_width -
graph_fontmetrics.stringWidth(status_mesg))/2,
basey +
(graph_height+graph_fontmetrics.getHeight())/2);
}
else g.drawImage (graph, basex, basey,
graph_width, graph_height, this);
xorpaint_cur_pointer(g);
if (show_saved) xorpaint_saved(g,0,nsaved-1);
} // end paint()
public void move_pointer_to (int x,int y)
{
int i, dx, dy;
// clear current pointer first
xorpaint_cur_pointer (applet_graphics);
curx = x;
cury = y;
if (nanchor==3)
{ // at the mature stage
dx = curx - anchorx[0];
dy = cury - anchory[0];
fcurx = (by*dx-bx*dy)/det + fanchorx[0];
fcury = (-ay*dx+ax*dy)/det + fanchory[0];
status_mesg = "s to save: " + fcurx + " " + fcury;
if (!in_graph(curx,cury))
status_mesg += " (warning: point out of graph)";
}
else status_mesg = "Move the pointer around... press " +
"return to submit your anchor " + (nanchor+1);
xorpaint_cur_pointer (applet_graphics);
// mouse click always highlights command TextField
goto_command_mode();
return;
} // end move_pointer_to()
public boolean calculate_frame()
{
int dx2, dy2, dx3, dy3;
double la2, lb2, la3, lb3, denom, modulus;
dx2 = anchorx[1] - anchorx[0];
dy2 = anchory[1] - anchory[0];
dx3 = anchorx[2] - anchorx[0];
dy3 = anchory[2] - anchory[0];
modulus = ( Math.abs(dx2) + Math.abs(dy2) +
Math.abs(dx3) + Math.abs(dy3) ) / 4;
// anchors too close in terms of screen resolution
if (modulus < pointer_size + 1) return false;
// anchors form straight line on screen
if (Math.abs((dx2/modulus*dy3/modulus-
dy2/modulus*dx3/modulus)) <
tolerable_relative_error) return false;
la2 = fanchorx[1] - fanchorx[0];
lb2 = fanchory[1] - fanchory[0];
la3 = fanchorx[2] - fanchorx[0];
lb3 = fanchory[2] - fanchory[0];
modulus = ( Math.abs(la2) + Math.abs(lb2) +
Math.abs(la3) + Math.abs(lb3) ) / 4;
// anchors too close in terms of value
if (modulus < tolerable_tiny) return false;
// anchors form straight line in value space
if (Math.abs((la2/modulus*lb3/modulus-
lb2/modulus*la3/modulus)) <
tolerable_relative_error) return false;
// matrix inversion and multiplication
denom = la2*lb3 - lb2*la3;
ax = (dx2*lb3-dx3*lb2) / denom;
ay = (dy2*lb3-dy3*lb2) / denom;
bx = (-dx2*la3+dx3*la2) / denom;
by = (-dy2*la3+dy3*la2) / denom;
det = ax*by - ay*bx;
return true;
} // end calculate_frame()
public void mouseClicked(MouseEvent e) {return;}
public void mouseExited(MouseEvent e) {return;}
public void mouseReleased(MouseEvent e) {return;}
public void mouseMoved(MouseEvent e) {return;}
public void mouseEntered(MouseEvent e)
{ // global status messaging
showStatus(status_mesg);
return;
} // end mouseEntered()
public void mousePressed(MouseEvent e)
{
// different with usual UNIX/C treatment
// because stupid BUTTON1_MASK could be 0
// System.out.println(e.getModifiers());
// System.out.println(e.CTRL_MASK + " " + e.SHIFT_MASK);
// System.out.println(e.BUTTON1_MASK + " " +
// e.BUTTON2_MASK + " " +
// e.BUTTON3_MASK + "\n");
switch (e.getModifiers())
{
case e.CTRL_MASK | e.BUTTON1_MASK: // left
case e.CTRL_MASK | e.BUTTON1_MASK & 15: // Netscape bug
move_pointer_to (curx-1, cury);
return;
case e.CTRL_MASK | e.BUTTON3_MASK: // right
move_pointer_to (curx+1, cury);
return;
case e.SHIFT_MASK | e.BUTTON1_MASK: // down
case e.SHIFT_MASK | e.BUTTON1_MASK & 15: // Netscape bug
move_pointer_to (curx, cury+1);
return;
case e.SHIFT_MASK | e.BUTTON3_MASK: // up
move_pointer_to (curx, cury-1);
return;
case e.CTRL_MASK | e.BUTTON2_MASK: // down
move_pointer_to (curx, cury+1);
return;
case e.SHIFT_MASK | e.BUTTON2_MASK: // up
move_pointer_to (curx, cury-1);
return;
default:
move_pointer_to(e.getX(),e.getY());
}
return;
} // end mousePressed()
public void goto_command_mode()
{
showStatus (status_mesg);
// freeze text input
T_Anchor.setEnabled(false);
B_Anchor.setEnabled(nanchor==3);
// activate command window
// T_Command.setEnabled(true);
// T_Command.requestFocus();
this.requestFocus();
return;
} // end goto_command_mode()
public void goto_input_mode()
{
showStatus (status_mesg);
// T_Command.setEnabled(false);
B_Anchor.setEnabled(true);
T_Anchor.setEnabled(true);
T_Anchor.requestFocus();
return;
} // end goto_input_mode()
public boolean isFocusTraversable() {return true;}
public void anchor_button_pressed()
{
String Anchor_Text;
Double G;
int i;
switch (nanchor)
{
case 0:
case 1:
case 2:
anchorx[nanchor] = curx;
anchory[nanchor] = cury;
try
{
Anchor_Text = T_Anchor.getText().trim();
i = Anchor_Text.indexOf(" ");
G = Double.valueOf(Anchor_Text.substring(0,i));
fanchorx[nanchor] = G.doubleValue();
G = Double.valueOf(Anchor_Text.substring(i+1));
fanchory[nanchor] = G.doubleValue();
status_mesg = "Anchor " + (nanchor+1) + " set at " +
fanchorx[nanchor] + " " + fanchory[nanchor] +
(nanchor==2?". Done! Click on":
". More chicks... [sic]");
}
catch (Exception e)
{
status_mesg =
"Wrong input: re-input two numbers separated by space";
goto_input_mode();
return;
}
// fool-proof help:
if (nanchor==1)
{ // second anchor just comes in
if ( (anchorx[1]==anchorx[0]) &&
(anchory[1]==anchory[0]) )
{
status_mesg =
"Same as anchor 1 on screen: reset anchor 2";
goto_command_mode();
return;
}
if ( (fanchorx[1]==fanchorx[0]) &&
(fanchory[1]==fanchory[0]) )
{
status_mesg =
"Same as anchor 1 in values: re-input anchor 2";
goto_input_mode();
return;
}
}
if (nanchor==2)
{ // third anchor just comes in
if ( (anchorx[2]==anchorx[0]) &&
(anchory[2]==anchory[0]) )
{
status_mesg =
"Same as anchor 1 on screen: reset anchor 3";
goto_command_mode();
return;
}
if ( (fanchorx[2]==fanchorx[0]) &&
(fanchory[2]==fanchory[0]) )
{
status_mesg =
"Same as anchor 1 in values: re-input anchor 3";
goto_input_mode();
return;
}
if ( (anchorx[2]==anchorx[1]) &&
(anchory[2]==anchory[1]) )
{
status_mesg =
"Same as anchor 2 on screen: reset anchor 3";
goto_command_mode();
return;
}
if ( (fanchorx[2]==fanchorx[1]) &&
(fanchory[2]==fanchory[1]) )
{
status_mesg =
"Same as anchor 2 in values: re-input anchor 3";
goto_input_mode();
return;
}
// check if the Jacobians are all right...
if ( !calculate_frame() )
{
nanchor = 0;
status_mesg = "Bad triple anchors: reset them all";
B_Anchor.setLabel(anchorname[nanchor]);
goto_command_mode();
return;
}
// pass all tests -> mature
}
nanchor++;
B_Anchor.setLabel(anchorname[nanchor]);
goto_command_mode();
return;
case 3: // now we are going back to where we started
// clear marked if painted
if (show_saved) xorpaint_saved(applet_graphics, 0, nsaved-1);
// abolish all previously saved
nsaved = 0;
nanchor = 0;
B_Anchor.setLabel(anchorname[nanchor]);
B_Print_Matlab.setEnabled(false);
B_Print_Latex.setEnabled(false);
B_Print_HTML.setEnabled(false);
C_Show_Saved.setEnabled(false);
status_mesg = "Move the pointer around... press " +
"return to submit your anchor " + (nanchor+1);
goto_command_mode();
return;
}
return;
} // end anchor_button_pressed()
public int pointer_stepsize (KeyEvent e)
{
if (e.isControlDown()) return POINTER_STEPSIZE_CONTORL;
else if (e.isShiftDown()) return POINTER_STEPSIZE_SHIFT;
else if (e.isAltDown()) return POINTER_STEPSIZE_ALT;
else if (e.isMetaDown()) return POINTER_STEPSIZE_META;
return 1;
} // end pointer_stepsize()
public void keyTyped (KeyEvent e){}
public void keyReleased (KeyEvent e)
{ // after TextField has done its own stuff
if (e.getSource() == T_Anchor)
switch (e.getKeyCode())
{
case e.VK_UNDEFINED:
case e.VK_ENTER:
return;
default:
status_mesg = "[" + T_Anchor.getText() + "]";
showStatus (status_mesg);
return;
}
return;
} // end keyReleased()
public void keyPressed (KeyEvent e)
{ // before TextField has done its own stuff
int i,j;
double d2,d2min;
if (e.getSource() == T_Anchor)
{ // input window events
switch (e.getKeyCode())
{
case e.VK_ENTER: // equivalent to press the button B_Anchor
anchor_button_pressed();
e.consume();
return;
case e.VK_X: // query status
showStatus ("x spy: " + status_mesg);
e.consume();
return;
}
return;
} // input window events
else
{ // command window events
e.consume();
// no need to show anything in the command TextField
switch (e.getKeyCode())
{
case e.VK_ENTER:
if (nanchor!=3)
{ // goto input window for data entry
status_mesg = "Now you can key in the values. " +
"Press return to submit";
if (already_been) T_Anchor.setText("");
else already_been = true;
goto_input_mode();
}
else // at mature stage
{ // prevent accidents
status_mesg = "Return is invalid now. " +
"To reset anchors, you must click the button";
showStatus (status_mesg);
}
return;
case e.VK_S: // save a new record
if (nanchor==3)
{ // at mature stage
if (nsaved >= MAXSAVE)
{
status_mesg = "Too much saved (" + MAXSAVE +
" rec.), reduce inventory please";
showStatus (status_mesg);
return;
}
// fcurx, fcury already evaluated by move_pointer_to()
savex[nsaved] = curx;
savey[nsaved] = cury;
fsavex[nsaved] = fcurx;
fsavey[nsaved] = fcury;
if (show_saved)
xorpaint_saved (applet_graphics, nsaved, nsaved);
nsaved++;
status_mesg = fcurx + " " + fcury +
" saved; total " + nsaved + " rec.";
if (nsaved==1)
{ // enable output channels
B_Print_Matlab.setEnabled(true);
B_Print_Latex.setEnabled(true);
B_Print_HTML.setEnabled(true);
C_Show_Saved.setEnabled(true);
}
}
else status_mesg =
"Cannot because the anchors are not yet set!";
showStatus (status_mesg);
return;
case e.VK_D: // delete nearest data to pointer
if (nsaved == 0)
status_mesg = "no records to be deleted";
else
{
for (j=-1,d2min=1E20,i=0; i<nsaved; i++)
{
d2 = (curx-savex[i])*(curx-savex[i])
+ (cury-savey[i])*(cury-savey[i]);
if (d2 <= d2min)
{
d2min = d2;
j = i;
}
}
// delete higher numbered images
if (show_saved)
xorpaint_saved (applet_graphics, j, nsaved-1);
for (i=j; i<nsaved-1; i++)
{
savex[i] = savex[i+1];
savey[i] = savey[i+1];
fsavex[i] = fsavex[i+1];
fsavey[i] = fsavey[i+1];
}
nsaved--;
if (show_saved)
xorpaint_saved (applet_graphics, j, nsaved-1);
status_mesg = "1 rec. deleted, " + nsaved +
" remaining";
}
if (nsaved==0)
{ // take away the toys
B_Print_Matlab.setEnabled(false);
B_Print_Latex.setEnabled(false);
B_Print_HTML.setEnabled(false);
C_Show_Saved.setEnabled(false);
}
showStatus (status_mesg);
return;
case e.VK_C: // delete all records
if (show_saved)
xorpaint_saved (applet_graphics, 0, nsaved-1);
nsaved = 0;
B_Print_Matlab.setEnabled(false);
B_Print_Latex.setEnabled(false);
B_Print_HTML.setEnabled(false);
C_Show_Saved.setEnabled(false);
status_mesg = "all records deleted";
showStatus(status_mesg);
return;
case e.VK_X: // query status
showStatus (status_mesg);
return;
case e.VK_LEFT:
move_pointer_to (curx-pointer_stepsize(e), cury);
return;
case e.VK_RIGHT:
move_pointer_to (curx+pointer_stepsize(e), cury);
return;
case e.VK_DOWN:
move_pointer_to (curx, cury+pointer_stepsize(e));
return;
case e.VK_UP:
move_pointer_to (curx, cury-pointer_stepsize(e));
return;
}
return;
} // command window events
} // end keyPressed()
public void actionPerformed (ActionEvent event)
{
Object object = event.getSource();
if (object == B_Anchor) anchor_button_pressed();
if (object == B_Print_Matlab) print_in_Matlab();
if (object == B_Print_Latex) print_in_Latex();
if (object == B_Print_HTML) print_in_HTML();
goto_command_mode();
return;
} // end actionPerformed()
public void itemStateChanged (ItemEvent e)
{ // could only come from C_Show_Saved checkbox
xorpaint_saved (applet_graphics, 0, nsaved-1);
show_saved = !show_saved;
goto_command_mode();
return;
} // end itemStateChanged()
public void print_in_Matlab()
{ // unformatted data in row order
int i;
System.out.println ("\n%% total " + nsaved +
" rec. %%");
for (i=0; i<nsaved; i++)
System.out.println (fsavex[i] + " " + fsavey[i]);
return;
} // end print_in_Matlab()
public void print_in_Latex()
{ // data in column order
int i;
String tmp, tmpn, tmpx, tmpy;
for (i=0, tmp="{|l", tmpn="No.", tmpx="X", tmpy="Y";
i<nsaved; i++)
{
tmp = tmp + "|c";
tmpn = tmpn + "& " + (i+1);
tmpx = tmpx + "& " + fsavex[i];
tmpy = tmpy + "& " + fsavey[i];
}
tmp = tmp + "|}";
tmpn = tmpn + "\\\\";
tmpx = tmpx + "\\\\";
tmpy = tmpy + "\\\\";
System.out.println ("\n%% total " + nsaved + " rec. %%");
System.out.println ("\\documentstyle[fullpage,12pt]{article}");
System.out.println ("\\begin{document}");
System.out.println ("\\begin{center}");
System.out.println ("Table I. X-Y Plot\\\\");
System.out.println ("\\begin{tiny}");
System.out.println ("\\begin{tabular}"+tmp+"\\hline");
System.out.println (tmpn);
System.out.println ("\\hline");
System.out.println (tmpx);
System.out.println ("\\hline");
System.out.println (tmpy);
System.out.println ("\\hline\\end{tabular}");
System.out.println ("\\end{tiny}");
System.out.println ("\\end{center}");
System.out.println ("\\end{document}");
} // end print_in_Latex()
public void print_in_HTML()
{
int i;
System.out.println ("\n<!-- total " + nsaved +
" rec. -->");
System.out.println ("<center><TABLE BORDER=1>");
System.out.println ("<TR><TH>#</TH><TH>X</TH><TH>Y</TH></TR>");
for (i=0; i<nsaved; i++)
System.out.println
("<TR><TH>" + (i+1) + "</TH><TH>" + fsavex[i] +
"</TH><TH>" + fsavey[i] + "</TH></TR>");
System.out.println ("</TABLE></center>");
} // end print_in_HTML()
public String getAppletInfo()
{
return "Graph Reader V2.0 (C) Ju Li (liju99@mit.edu)";
} // end getAppletInfo()
} // end class reader
Back to the GraphReader applet page
New on the Java Boutique:
New Review:
Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling
API boasts simplicity, ease-of-integration, a well-rounded feature
set, and it's free!
New Applet:
Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA
sequences into three useful formats.
Elsewhere on internet.com:
WebDeveloper Java
Lots of Java information on webdeveloper.com
WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.
ScriptSearch Java
Hundreds of free Java code files to download.
jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.
|