P
Phil Powell
import java.io.*;
import java.net.*;
import java.awt.*;
import java.util.*;
import java.applet.*;
import java.awt.event.*;
/**
* @version JDK 1.3
* @author Phil Powell
*/
/*---------------------------------------------------------------------------------------------
* ParseNews will receive a Phil-homegrown XML-like script from a PHP
file, parse through it,
* and will display each news item within the applet. The "View News"
button, upon being
* pressed, will perform an AppletContext showDocument action to go to
the URL formed by the
* passed ID per Vector iteration. News items will continually scroll
from bottom to top and
* then revert back to the first one
*
* Created 2/1/2003
*--------------------------------------------------------------------------------------------*/
public class ParseNews extends Applet {
// INITIALIZE VARS AND VAR SCOPE
protected Vector parseVector = new Vector();
protected Thread scrollThread = null;
protected ActionListener al = null;
private int xpos = 0, ypos = 0, index = 0;
private boolean hasStartedScroll = false, hasAddedAction = false;
private Button newsButton = new Button("View News");
private Panel scrollPanel, buttonPanel;
/*----------------------------------------------------------------------------------
* Vector method parser will return a vector of a 3-item array
containing the id,
* shortdescription and ranking of what was passed from the PHP
script
*
*----------------------------------------------------------------------------------*/
private Vector parser(String stuff) {
// STUFF
}
/*------------------------------------------------------------------------------------------
* Vector method sortedVector will sort the vector created by parser
into numerical order
* according to the ranking value found as the third element of each
3-item array found in
* each vector element
*
*------------------------------------------------------------------------------------------*/
private Vector sortedVector(Vector vectorToSort) {
// STUFF
}
// BUBBLE SORT INTEGER ARRAY METHOD - IN LIEU OF M$ NOT ALLOWING FOR
JAVA.UTIL.ARRAYS - GRRRR
private int[] mySortedArray(int[] origArray) {
// STUFF
}
/*------------------------------------------------------------------------------------------
* unescapeHTML String method will convert ASCII characters to their
"funky" equivalent.
*
* originally created by Rene Gagnon at
http://www.rgagnon.com/javadetails/java-0307.html
* Modified by Phil Powell on 2/2/2003
*
*-----------------------------------------------------------------------------------------*/
public static String unescapeHTML(String schtuff) {
String[][] asciiArray =
{{"<", "<"}, {">", ">" }, {"&", "&" }, {""", "\""},
{"à", "à"},
{"À", "À"}, {"â", "â"}, {"ä", "ä"}, {"Ä",
"Ä"}, {"Â", "Â"},
{"å", "å"}, {"Å", "Å"}, {"æ", "æ"}, {"Æ",
"Æ"}, {"ç", "ç"},
{"Ç", "Ç"}, {"é", "é"}, {"É", "É"},
{"è", "è"},
{"È", "È"}, {"ê", "ê"}, {"Ê", "Ê"}, {"ë",
"ë"}, {"Ë", "Ë"},
{"ï", "ï"}, {"Ï", "Ï"}, {"ô", "ô"}, {"Ô",
"Ô"}, {"ö", "ö"},
{"Ö", "Ö"}, {"ø", "ø"}, {"Ø", "Ø"}, {"ß",
"ß"},
{"ù", "ù"}, {"Ù", "Ù"}, {"û", "û"},
{"Û", "Û"},
{"ü", "ü"}, {"Ü", "Ü"}, {" ", " "}, {"®",
"\u00a9"}, {"©", "\u00ae"},
{"€", "\u20a0"}
};
int flag = -1, ampIndex = -1;
if (schtuff.indexOf("&") >= 0) {
if (schtuff.indexOf(";") > schtuff.indexOf("&")) {
String asciiStuff = schtuff.substring(schtuff.indexOf("&"),
schtuff.indexOf(";") + 1);
ampIndex = schtuff.indexOf("&");
while (asciiStuff.substring(1, asciiStuff.length()).indexOf("&")
asciiStuff = asciiStuff.substring(1, asciiStuff.length()).trim();
}
for (int j = 0; j < asciiArray.length; j++) {
if (asciiArray[j][0].equals(asciiStuff)) {
flag = j;
break;
}
}
if (flag >= 0) {
schtuff = schtuff.substring(0, ampIndex) + asciiArray[flag][1] +
schtuff.substring(schtuff.indexOf(";") + 1,
schtuff.length());
return unescapeHTML(schtuff); // RECURSIVE
}
}
return schtuff;
} else {
return schtuff.trim();
}
}
// INITIALIZE APPLET, RETRIEVE VALUES FROM PHP SCRIPT AND SORT INTO
VECTOR
public void init() {
String stuff = null;
try {
URL url = new URL(getParameter("url"));
URLConnection conn = url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(false);
conn.setUseCaches(false);
conn.setDefaultUseCaches(false);
conn.setRequestProperty("Content-type", "text/html");
BufferedReader fromURL = new BufferedReader(new
InputStreamReader(conn.getInputStream()));
stuff = fromURL.readLine();
// CLOSE CONNECTION
fromURL.close();
fromURL = null;
conn = null;
} catch (Exception e) {
parseVector.addElement(new String[]{"0", "Could not connect to
retrieve news", "0"});
}
if (stuff != null && stuff != "") {
parseVector = parser(stuff);
} else if (parseVector.size() == 0) {
parseVector.addElement(new String[]{"0", "No current news found",
"0"});
}
setBackground(Color.black);
setForeground(Color.white);
setFont(new Font("Garamond", Font.BOLD, 10));
scrollPanel = new Panel();
scrollPanel.setVisible(false);
buttonPanel = new Panel();
buttonPanel.setBackground(Color.black);
buttonPanel.setForeground(Color.white);
newsButton.setBackground(Color.red);
newsButton.setForeground(Color.white);
// ONLY ADD THE "VIEW NEWS" BUTTON IF THERE IS NEWS TO VIEW!
if (((String[])parseVector.elementAt(0))[0] != "0") {
buttonPanel.add(newsButton);
} else {
buttonPanel.setVisible(false);
}
add(scrollPanel);
add(buttonPanel);
scrollThread = new Thread(new ScrollNews());
scrollThread.start();
}
/*------------------------------------------------------------------------------------------
* Reinitialize value of the ActionListener object for the "View
News" button, along with
* display news item, with the "scrolling" effect handled by the
runnable class ScrollNews
*-----------------------------------------------------------------------------------------*/
public void paint(Graphics g) {
FontMetrics fm = g.getFontMetrics();
((String[])parseVector.elementAt(index))[1] =
unescapeHTML(((String[])parseVector.elementAt(index))[1]);
xpos = (getSize().width -
fm.stringWidth(((String[])parseVector.elementAt(index))[1])) / 2;
if (ypos <= 0) {
g.drawString("", 0, 0); // CLEAR THE APPLET
ypos = getSize().height;
hasAddedAction = false;
if (((String[])parseVector.elementAt(0))[0] != "0")
newsButton.removeActionListener(al);
if (index < parseVector.size() - 1 && hasStartedScroll) {
index++;
} else if (index > 0) {
index = 0;
hasStartedScroll = false;
}
}
if (((String[])parseVector.elementAt(0))[0] != "0" &&
!hasAddedAction) {
hasAddedAction = true;
al = new ViewNews("http://valsignalandet.com/cgi-bin/cgiwrap/ppowell/news.cgi?id="
+
((String[])parseVector.elementAt(index))[0]);
newsButton.addActionListener(al);
}
g.drawString(((String[])parseVector.elementAt(index))[1], xpos,
ypos);
hasStartedScroll = true;
}
class ScrollNews implements Runnable {
public void run() {
while (true) {
ypos = ypos - 1;
ParseNews.this.repaint();
try {
Thread.sleep(50);
} catch (InterruptedException e) {}
}
}
}
class ViewNews implements ActionListener {
private String urlString = "";
public ViewNews(String urlString) {
this.urlString = urlString;
}
public void actionPerformed(ActionEvent e) {
try {
ParseNews.this.getAppletContext().showDocument(new
URL(urlString));
} catch (Exception oops) {
System.out.println("could not go to " + urlString);
oops.printStackTrace();
}
}
}
}
The following applet I wrote had run just fine on my website until
sometime today, when it suddenly started running at an extremely slow
rate. I tried everything I could think of, including garbage
collection, to alleviate the problem, to no avail.
I am suspecting a memory leak somewhere but I cannot discern where.
Can anyone with more Java knowledge out there discern this for me or
at least tell me what steps I should be taking in my code to prevent
memory leaks for a continually-running applet?
Thanx
Phil
import java.net.*;
import java.awt.*;
import java.util.*;
import java.applet.*;
import java.awt.event.*;
/**
* @version JDK 1.3
* @author Phil Powell
*/
/*---------------------------------------------------------------------------------------------
* ParseNews will receive a Phil-homegrown XML-like script from a PHP
file, parse through it,
* and will display each news item within the applet. The "View News"
button, upon being
* pressed, will perform an AppletContext showDocument action to go to
the URL formed by the
* passed ID per Vector iteration. News items will continually scroll
from bottom to top and
* then revert back to the first one
*
* Created 2/1/2003
*--------------------------------------------------------------------------------------------*/
public class ParseNews extends Applet {
// INITIALIZE VARS AND VAR SCOPE
protected Vector parseVector = new Vector();
protected Thread scrollThread = null;
protected ActionListener al = null;
private int xpos = 0, ypos = 0, index = 0;
private boolean hasStartedScroll = false, hasAddedAction = false;
private Button newsButton = new Button("View News");
private Panel scrollPanel, buttonPanel;
/*----------------------------------------------------------------------------------
* Vector method parser will return a vector of a 3-item array
containing the id,
* shortdescription and ranking of what was passed from the PHP
script
*
*----------------------------------------------------------------------------------*/
private Vector parser(String stuff) {
// STUFF
}
/*------------------------------------------------------------------------------------------
* Vector method sortedVector will sort the vector created by parser
into numerical order
* according to the ranking value found as the third element of each
3-item array found in
* each vector element
*
*------------------------------------------------------------------------------------------*/
private Vector sortedVector(Vector vectorToSort) {
// STUFF
}
// BUBBLE SORT INTEGER ARRAY METHOD - IN LIEU OF M$ NOT ALLOWING FOR
JAVA.UTIL.ARRAYS - GRRRR
private int[] mySortedArray(int[] origArray) {
// STUFF
}
/*------------------------------------------------------------------------------------------
* unescapeHTML String method will convert ASCII characters to their
"funky" equivalent.
*
* originally created by Rene Gagnon at
http://www.rgagnon.com/javadetails/java-0307.html
* Modified by Phil Powell on 2/2/2003
*
*-----------------------------------------------------------------------------------------*/
public static String unescapeHTML(String schtuff) {
String[][] asciiArray =
{{"<", "<"}, {">", ">" }, {"&", "&" }, {""", "\""},
{"à", "à"},
{"À", "À"}, {"â", "â"}, {"ä", "ä"}, {"Ä",
"Ä"}, {"Â", "Â"},
{"å", "å"}, {"Å", "Å"}, {"æ", "æ"}, {"Æ",
"Æ"}, {"ç", "ç"},
{"Ç", "Ç"}, {"é", "é"}, {"É", "É"},
{"è", "è"},
{"È", "È"}, {"ê", "ê"}, {"Ê", "Ê"}, {"ë",
"ë"}, {"Ë", "Ë"},
{"ï", "ï"}, {"Ï", "Ï"}, {"ô", "ô"}, {"Ô",
"Ô"}, {"ö", "ö"},
{"Ö", "Ö"}, {"ø", "ø"}, {"Ø", "Ø"}, {"ß",
"ß"},
{"ù", "ù"}, {"Ù", "Ù"}, {"û", "û"},
{"Û", "Û"},
{"ü", "ü"}, {"Ü", "Ü"}, {" ", " "}, {"®",
"\u00a9"}, {"©", "\u00ae"},
{"€", "\u20a0"}
};
int flag = -1, ampIndex = -1;
if (schtuff.indexOf("&") >= 0) {
if (schtuff.indexOf(";") > schtuff.indexOf("&")) {
String asciiStuff = schtuff.substring(schtuff.indexOf("&"),
schtuff.indexOf(";") + 1);
ampIndex = schtuff.indexOf("&");
while (asciiStuff.substring(1, asciiStuff.length()).indexOf("&")
ampIndex = schtuff.indexOf("&", ampIndex + 1);= 0) {
asciiStuff = asciiStuff.substring(1, asciiStuff.length()).trim();
}
for (int j = 0; j < asciiArray.length; j++) {
if (asciiArray[j][0].equals(asciiStuff)) {
flag = j;
break;
}
}
if (flag >= 0) {
schtuff = schtuff.substring(0, ampIndex) + asciiArray[flag][1] +
schtuff.substring(schtuff.indexOf(";") + 1,
schtuff.length());
return unescapeHTML(schtuff); // RECURSIVE
}
}
return schtuff;
} else {
return schtuff.trim();
}
}
// INITIALIZE APPLET, RETRIEVE VALUES FROM PHP SCRIPT AND SORT INTO
VECTOR
public void init() {
String stuff = null;
try {
URL url = new URL(getParameter("url"));
URLConnection conn = url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(false);
conn.setUseCaches(false);
conn.setDefaultUseCaches(false);
conn.setRequestProperty("Content-type", "text/html");
BufferedReader fromURL = new BufferedReader(new
InputStreamReader(conn.getInputStream()));
stuff = fromURL.readLine();
// CLOSE CONNECTION
fromURL.close();
fromURL = null;
conn = null;
} catch (Exception e) {
parseVector.addElement(new String[]{"0", "Could not connect to
retrieve news", "0"});
}
if (stuff != null && stuff != "") {
parseVector = parser(stuff);
} else if (parseVector.size() == 0) {
parseVector.addElement(new String[]{"0", "No current news found",
"0"});
}
setBackground(Color.black);
setForeground(Color.white);
setFont(new Font("Garamond", Font.BOLD, 10));
scrollPanel = new Panel();
scrollPanel.setVisible(false);
buttonPanel = new Panel();
buttonPanel.setBackground(Color.black);
buttonPanel.setForeground(Color.white);
newsButton.setBackground(Color.red);
newsButton.setForeground(Color.white);
// ONLY ADD THE "VIEW NEWS" BUTTON IF THERE IS NEWS TO VIEW!
if (((String[])parseVector.elementAt(0))[0] != "0") {
buttonPanel.add(newsButton);
} else {
buttonPanel.setVisible(false);
}
add(scrollPanel);
add(buttonPanel);
scrollThread = new Thread(new ScrollNews());
scrollThread.start();
}
/*------------------------------------------------------------------------------------------
* Reinitialize value of the ActionListener object for the "View
News" button, along with
* display news item, with the "scrolling" effect handled by the
runnable class ScrollNews
*-----------------------------------------------------------------------------------------*/
public void paint(Graphics g) {
FontMetrics fm = g.getFontMetrics();
((String[])parseVector.elementAt(index))[1] =
unescapeHTML(((String[])parseVector.elementAt(index))[1]);
xpos = (getSize().width -
fm.stringWidth(((String[])parseVector.elementAt(index))[1])) / 2;
if (ypos <= 0) {
g.drawString("", 0, 0); // CLEAR THE APPLET
ypos = getSize().height;
hasAddedAction = false;
if (((String[])parseVector.elementAt(0))[0] != "0")
newsButton.removeActionListener(al);
if (index < parseVector.size() - 1 && hasStartedScroll) {
index++;
} else if (index > 0) {
index = 0;
hasStartedScroll = false;
}
}
if (((String[])parseVector.elementAt(0))[0] != "0" &&
!hasAddedAction) {
hasAddedAction = true;
al = new ViewNews("http://valsignalandet.com/cgi-bin/cgiwrap/ppowell/news.cgi?id="
+
((String[])parseVector.elementAt(index))[0]);
newsButton.addActionListener(al);
}
g.drawString(((String[])parseVector.elementAt(index))[1], xpos,
ypos);
hasStartedScroll = true;
}
class ScrollNews implements Runnable {
public void run() {
while (true) {
ypos = ypos - 1;
ParseNews.this.repaint();
try {
Thread.sleep(50);
} catch (InterruptedException e) {}
}
}
}
class ViewNews implements ActionListener {
private String urlString = "";
public ViewNews(String urlString) {
this.urlString = urlString;
}
public void actionPerformed(ActionEvent e) {
try {
ParseNews.this.getAppletContext().showDocument(new
URL(urlString));
} catch (Exception oops) {
System.out.println("could not go to " + urlString);
oops.printStackTrace();
}
}
}
}
The following applet I wrote had run just fine on my website until
sometime today, when it suddenly started running at an extremely slow
rate. I tried everything I could think of, including garbage
collection, to alleviate the problem, to no avail.
I am suspecting a memory leak somewhere but I cannot discern where.
Can anyone with more Java knowledge out there discern this for me or
at least tell me what steps I should be taking in my code to prevent
memory leaks for a continually-running applet?
Thanx
Phil