I'm struggling with a new program.
The program is designed to obtain a spectrum from a webcam and compare it with a reference spectrum. This is done when the use clicks a button called 'captureButton'.
At the end of the operation, the program displays a plot of the spectrum (created externally via a batch file through Scilab) in a message dialogue. This all happens perfectly and as expected. However, if the operation is run again (by pressing the button again) the process takes place fine, but the image displayed in the message dialogue is the old image from the previous run.
This happens despite the fact that at the beginning of the operation, all old files are erased and then recreated using the new data.
I suspect then that the old image is somehow being stored in the memory, rather than being recalled from the new file the second time around.
I've tried requesting the garbage collector, to no effect.
Here is the code (I've removed irrelevant segments as this is a fairly long code)...
//Imports etc here
public class VSAWindow extends javax.swing.JFrame {
public VSAWindow() {
initComponents();
//Set defaults for user input
sampleText.setText("50");
toleranceText.setText("1");
acceptanceText.setText("10");
//Clear Calibration window and set calibration spectrum image
jLabel10.setText("");
jLabel11.setText("");
ImageIcon icon = new ImageIcon("reference/mainspectrum.png");
jLabel10.setIcon(icon);
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
captureButton = new javax.swing.JButton();
// Some other declarations...
jButton1 = new javax.swing.JButton();
calibrateButton = new javax.swing.JButton();
jLabel10 = new javax.swing.JLabel();
jLabel11 = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
captureButton.setText("Capture");
captureButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
captureButtonActionPerformed(evt);
}
});
//Some code which sets a load of text on screen...
jButton1.setText("EXIT");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
jLabel10.setText("jLabel10");
jLabel11.setText("jLabel11");
//A load of code added by the IDE for adding various components
private void captureButtonActionPerformed(java.awt.event.ActionEvent evt) {
//CLEAR ALL PREVIOUS IF POSSIBLE
System.gc();
//Check user input values for validity
try {
String smpIn = sampleText.getText();
String tolIn = toleranceText.getText();
String accIn = acceptanceText.getText();
int smpVl = Integer.parseInt(smpIn);
double tolVl = Integer.parseInt(tolIn);
int accVl = Integer.parseInt(accIn);
int stopgo = 0; //Condition variable to prevent invalid operation
if (smpVl >= 0 && smpVl <= 766 && tolVl >= 0 && tolVl <= 100 && accVl >= 0 && accVl <= 100) {
stopgo = 1;
}
if (stopgo == 1) {//Proceed if input values have been checked for validity
try {
//BEFORE BEGINNING CLEAR ALL FILES FROM PREVIOUS RUNS
//This will prevent old data from being displayed in
//the event of system slowdown
File del1 = new File("convert.bat");
File del2 = new File("inplot.png");
File del3 = new File("newdata.csv");
File del4 = new File("peakdata.csv");
File del5 = new File("peaks.sce");
File del6 = new File("refbat.bat");
File del7 = new File("refplot.png");
File del8 = new File("rgb.sce");
File del9 = new File("rgbbat.bat");
File del10 = new File("test.png");
File del11 = new File("spectra\\newspectrum.ppm");
File del12 = new File("spectra\\convspectrum.doc");
del1.delete();
del2.delete();
del3.delete();
del4.delete();
del5.delete();
del6.delete();
del7.delete();
del8.delete();
del9.delete();
del10.delete();
del11.delete();
del12.delete();
//CAPTURE SPECTRUM IMAGE
Webcam webcam = Webcam.getDefault();
Dimension size = new Dimension(640, 480);
webcam.setViewSize(size);
webcam.open();
BufferedImage image = webcam.getImage();
try {
ImageIO.write(image, "PNG", new File("test.png"));
} catch (IOException ex) {
Logger.getLogger(VSAWindow.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Obtaining data from spectrometer...");
//CREATE BATCH FILE FOR IMAGE CONVERSION TO .PPM FORMAT
String filename = "convert.bat";
WriteFile data = new WriteFile(filename, false);
WriteFile dataline = new WriteFile(filename, true);
data.WriteToFile("cd \"C:\\Program Files (x86)\\IrfanView\"");
dataline.WriteToFile("i_view32.exe C:\\Users\\Guy\\Documents\\NetBeansProjects\\VSpecAnalyser\\test.png /convert=C:\\Users\\Guy\\Documents\\NetBeansProjects\\VSpecAnalyser\\spectra\\newspectrum.ppm");
dataline.WriteToFile("exit");
//Wait for processes to finish...
File f = new File("test.png");
int msgCheck = 0;//Variable to prevent repeated i/o
while (!f.exists()) {
if (msgCheck == 0) {
System.out.println("Building spectral data...");
}
msgCheck = 1;
}
//Shuts webcam and proceeds as long as input has been obtained
webcam.close();
//EXECUTE CONVERSION BATCH FILE
Runtime.getRuntime().exec("cmd /c start convert.bat");
//CONVERSION BY TO LINE BY LINE FORMAT - NEEDS STREAMLINING SOMEHOW
//Wait for file to be created:
File fn = new File("spectra\\newspectrum.ppm");
int msgCheck2 = 0;//Variable to prevent repeated i/o
while (!fn.exists()) {
if (msgCheck2 == 0) {
System.out.println("Performing file operations....");
}
msgCheck2 = 1;
}//Proceeds once file has been converted and placed in 'spectra' folder
//Open file for format conversion
ReadFile open = new ReadFile("C:\\Users\\Guy\\Documents\\NetBeansProjects\\VSpecAnalyser\\spectra\\newspectrum.ppm");
String[] readLines;
readLines = open.OpenFile();
//Prepare Writefile
WriteFile begin = new WriteFile("C:\\Users\\Guy\\Documents\\NetBeansProjects\\VSpecAnalyser\\spectra\\convspectrum.doc", false);
begin.WriteToFile("");
//Create file append code
WriteFile write = new WriteFile("C:\\Users\\Guy\\Documents\\NetBeansProjects\\VSpecAnalyser\\spectra\\convspectrum.doc", true);
//Begin looping and adding to new file
String columns = readLines[2].split("\\ ")[0];
int nos = Integer.parseInt(columns);
for (int i = 0; i < readLines.length; i++) {
if (i < 4) {
write.WriteToFile(readLines[i]);
} else if (i == 2) {
//Splits condensed data and rebuilds as line-by-line format
} else if (i >= 4 && i < nos) {
String[] lnMk = readLines[i].split("[\\W]");
for (int j = 0; j < lnMk.length; j++) {
write.WriteToFile(lnMk[j]);
}
}
}
//BEGIN DATA ANALYSIS
//FILE READING PROCEDURE
ReadFile file = new ReadFile("spectra/convspectrum.doc");//Read in filename to be opened
String aryLines[];//Declare string array for file contents in line by line read
aryLines = file.OpenFile();//Read file line by line and assign each line to a sequential array index
//DECLARE VARIABLES
String beforeSpc = aryLines[3].split("\\ ")[0];
System.out.println("Number of columns = " + beforeSpc);
int docWidth = Integer.parseInt(beforeSpc);//Gets spectrum width from file header
int rgbCount = 0;//Index for counting final RGB indices
int sample = smpVl;//Declares lower limit for sampling (Sample = r+g+b)(min=0, max = 765)
String[] rgbArray = new String[aryLines.length];//Declare array for storage of final RGB values
//CREATE CSV FILE FOR SCILAB - INPUT SPECTRUM
WriteFile newData = new WriteFile("newdata.csv", false);
newData.WriteToFile("");
//CREATE SCILAB SCRIPT FILE - INPUT SPECTRUM
WriteFile createSciRGB = new WriteFile("rgb.sce", false);
createSciRGB.WriteToFile("");
//CONFIGURE SCILAB SCRIPT FOR RGB DATA - INPUT SPECTRUM
WriteFile addSciRGB = new WriteFile("rgb.sce", true);
addSciRGB.WriteToFile("cd(\"C:\\Users\\Guy\\Documents\\NetBeansProjects\\VSpecAnalyser\");");
addSciRGB.WriteToFile("y = evstr(read_csv(\"newdata.csv\"));");
addSciRGB.WriteToFile("xlabel(\"Wavelength (nm)\")");
addSciRGB.WriteToFile("ylabel(\"Intesity (Combined RGB Value)\")");
addSciRGB.WriteToFile("plot2d(y)");
addSciRGB.WriteToFile("xs2png(0, \"inplot.png\" )");
addSciRGB.WriteToFile("exit");
//CREATE BATCH FILE FOR RUNNING SCILAB (RGB INPUT SPECTRUM)
WriteFile rgbBat = new WriteFile("rgbbat.bat", false);
rgbBat.WriteToFile("\"C:/Program Files/scilab-5.5.0/bin/Scilex.exe\" scilab-adv-cli -f \"rgb.sce\" -nw");
WriteFile addRgbBat = new WriteFile("rgbbat.bat", true);
addRgbBat.WriteToFile("exit");
//BEGIN LOOPING THROUGH INPUT FILE
for (int i = 0; i < 3 * docWidth; i++) {//Restricts loop to single line by stopping after 1x width of sample spectrum
//System.out.println(aryLines[i]);
if (i >= 6 && i % 3 == 0) {
//ASSIGN R,G,B VALUES
int r = Integer.parseInt(aryLines[i - 2]);
int g = Integer.parseInt(aryLines[i - 1]);
int b = Integer.parseInt(aryLines[i]);
int dataR = Integer.parseInt(aryLines[i - 2]);
int dataG = Integer.parseInt(aryLines[i - 1]);
int dataB = Integer.parseInt(aryLines[i]);
int lineSpec = dataR + dataG + dataB;
String dataPoint = Integer.toString(lineSpec);
//ADD RGB DATA TO SCILAB FILE - INPUT SPECTRUM
WriteFile peaks = new WriteFile("newdata.csv", true);
peaks.WriteToFile(dataPoint);
int pixSum = r + g + b;//Creates measure of pixel significance
if (pixSum > sample) {
rgbArray[rgbCount] = aryLines[i - 2] + " " + aryLines[i - 1] + " " + aryLines[i];
rgbCount++;
}
}
}
//OUTPUT ARRAY OF FINAL RGB VALUES
for (int j = 0; j < rgbArray.length; j++) {
if (rgbArray[j] != null) {
System.out.println(rgbArray[j]);
}
}
//END COLLECTION OF INPUT DATA
//BEGIN CREATION OF COMPARISON DATA
//FILE READING PROCEDURE FOR REFERENCE SPECTRUM
ReadFile specFile = new ReadFile("reference/mainspectrum.ppm");//Read in filename to be opened
String specLines[];//Declare string array for file contents in line by line read
specLines = specFile.OpenFile();//Read file line by line and assign each line to a sequential array index
//DECLARE VARIABLES
String specBeforeSpc = specLines[2].split("\\ ")[0];//Gets spectrum width from file header
System.out.println("Number of columns = " + specBeforeSpc);
int specWidth = Integer.parseInt(specBeforeSpc);
int specCount = 0;//Index for counting reference RGB indices
String[] specArray = new String[specWidth];//Declare array for storage of reference RGB values
//CREATE CSV FILE FOR SCILAB - REFERENCE SPECTRUM
WriteFile stFile = new WriteFile("peakdata.csv", false);//Creates and clears file for line spectrum data
stFile.WriteToFile("");
//CREATE SCILAB SCRIPT FILE - REFERENCE SPECTRUM
WriteFile createSciSpec = new WriteFile("peaks.sce", false);
createSciSpec.WriteToFile("");
//CONFIGURE SCILAB SCRIPT FOR RGB DATA - REFERENCE SPECTRUM
WriteFile addSciSpec = new WriteFile("peaks.sce", true);
addSciSpec.WriteToFile("cd(\"C:\\Users\\Guy\\Documents\\NetBeansProjects\\VSpecAnalyser\");");
addSciSpec.WriteToFile("y = evstr(read_csv(\"peakdata.csv\"));");
addSciSpec.WriteToFile("xlabel(\"Wavelength (nm)\")");
addSciSpec.WriteToFile("ylabel(\"Intesity (Combined RGB Value)\")");
addSciSpec.WriteToFile("plot2d(y)");
addSciSpec.WriteToFile("xs2png(0, \"refplot.png\" )");
addSciSpec.WriteToFile("exit");
//CREATE BATCH FILE FOR RUNNING SCILAB (REFERENCE SPECTRUM)
WriteFile refBat = new WriteFile("refbat.bat", false);
refBat.WriteToFile("\"C:/Program Files/scilab-5.5.0/bin/Scilex.exe\" scilab-adv-cli -f \"peaks.sce\" -nw");
WriteFile addRefBat = new WriteFile("refbat.bat", true);
addRefBat.WriteToFile("exit");
//BEGIN LOOPING THROUGH SPECTRUM REFERENCE FILE
for (int i = 0; i < 3 * specWidth; i++) {//Restricts loop to single line by stopping after 1x width of reference spectrum
//Eliminate header and compress RGB lines into single, 3 point entries
if (i >= 6 && i % 3 == 0) {
//ASSIGN R,G,B VALUES TO REFERENCE SPECTRUM ARRAY
specArray[specCount] = specLines[i - 2] + " " + specLines[i - 1] + " " + specLines[i];
specCount++;
int dataR = Integer.parseInt(specLines[i - 2]);
int dataG = Integer.parseInt(specLines[i - 1]);
int dataB = Integer.parseInt(specLines[i]);
int lineSpec = dataR + dataG + dataB;
String dataPoint = Integer.toString(lineSpec);
//ADD DATA TO SCILAB FILE - REFERENCE SPECTRUM
WriteFile peaks = new WriteFile("peakdata.csv", true);
peaks.WriteToFile(dataPoint);
}
}
System.out.println("Reference Spectrum Obtained");
//COMPARE INPUT AND REFERENCE SPECTRA
//Set matching tolerance:
double tol = (765 / 100) * tolVl;
//Set lower threshold for partial matches
int disp = 100 - accVl;
//Find length of input RGB input array to prevent null pointers
int rgbLength = 0;
//Declare null variables for match counts
int matchCount = 0;
int perfCount = 0;
int possCount = 0;
//Determine length of RGB Input data array
for (int x = 0; x < rgbArray.length; x++) {
if (rgbArray[x] != null) {
rgbLength++;
}
}
//BEGIN COMPARISON
//Check each input RGB value...
for (int l = 0; l < rgbLength; l++) {
String[] colours = rgbArray[l].split(" ");
String sred = colours[0];
String sgreen = colours[1];
String sblue = colours[2];
int red = Integer.parseInt(sred);
int green = Integer.parseInt(sgreen);
int blue = Integer.parseInt(sblue);
//...against each reference value
for (int m = 0; m < specArray.length - 2; m++) {
String[] cols = specArray[m].split(" ");
String sr = cols[0];
String sg = cols[1];
String sb = cols[2];
int r = Integer.parseInt(sr);
int g = Integer.parseInt(sg);
int b = Integer.parseInt(sb);
double wavelength = 380 + m / 3;
//Identify perfect matches
if (red == r && green == g && blue == b) {
perfCount++;
matchCount++;
System.out.println("PERFECT MATCH! Found at " + m + " of reference and " + l + " of input");
//Some code to output results
//Identify imperfect matches based on tolerance
} else if (red - r < tol && green - g < tol && blue - b < tol && red - r > -tol && green - g > -tol && blue - b > -tol) {
//Calculate possible matches regardless of parameters
possCount++;
//CALCULATE MATCH QUALITY
//Initialise variables
double rperc = 100;
double gperc = 100;
double bperc = 100;
double tperc = 100;
//Provide conditions
if (red > r) {
rperc = (100 / (double) red) * (double) r;
} else if (red < r) {
rperc = (100 / (double) r) * (double) red;
}
if (green > g) {
gperc = (100 / (double) green) * (double) g;
} else if (green < g) {
gperc = (100 / (double) g) * (double) green;
}
if (blue > b) {
bperc = (100 / (double) blue) * (double) b;
} else if (blue < b) {
bperc = (100 / (double) b) * (double) blue;
}
//Small discrepancies involving zero values are automatically given a 95% quality rating
if (r == 0 || red == 0) {
rperc = 95;
}
if (g == 0 || green == 0) {
gperc = 95;
}
if (b == 0 || blue == 0) {
bperc = 95;
}
if (red == r) {
rperc = 100;
}
if (green == g) {
gperc = 100;
}
if (blue == b) {
bperc = 100;
}
double tot = (tperc / 300) * (rperc + gperc + bperc);
//Check whether available matches are within specified range
if (tot > disp) {
matchCount++;
//Display Match parameters
System.out.println("Partial MATCH! Found at " + m + " of reference and " + l + " of input");
//Some more code to output results
//Calculate and display final quality value and breakdown
System.out.println("Match Quality: " + tot + "% (R: " + rperc + " G: " + gperc + " B: " + bperc);
}
}
}
}
//More results
//CHECK THAT BATCH FILES FOR PLOTTING EXIST
File chkrgb = new File("rgbbat.bat");
File chkref = new File("refbat.bat");
while (!chkrgb.exists()) {
//Do nothing, just wait
}
while (!chkref.exists()) {
//Do nothing, just wait
}
//PRODUCE SCILAB PLOTS FOR BOTH REFERENCE AND INPUT SPECTRA
Runtime.getRuntime().exec("cmd /c start refbat.bat");
Runtime.getRuntime().exec("cmd /c start rgbbat.bat");
//CHECK PNG PLOTS HAVE BEEN GENERATED
File chkrgbpng = new File("inplot.png");
File chkrefpng = new File("refplot.png");
while (!chkrgbpng.exists()) {
System.out.println("Loading RGB Plot...");
Thread.sleep(2000);
}
while (!chkrefpng.exists()) {
System.out.println("Loading Reference Plot...");
Thread.sleep(2000);
}
//PLACE RGB PLOT IN WINDOW
System.out.println("Setting plot to screen...");
ImageIcon icon2 = new ImageIcon("inplot.png");
String msgTitle = "";
String msgCaption = "Wavelength in nm";
JOptionPane.showMessageDialog(null, msgCaption, msgTitle, JOptionPane.INFORMATION_MESSAGE, icon2);
} catch (IOException ex) {
Logger.getLogger(VSAWindow.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
JOptionPane.showMessageDialog(null, "Please select valid input values!");
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
System.exit(0);
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(VSAWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(VSAWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(VSAWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(VSAWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new VSAWindow().setVisible(true);
}
});
}
// Variables declaration - do not modify
// End of variables declaration
}
The Image in question is 'icon2', near the end of the code, beneath the comment "//PLACE RGB PLOT IN WINDOW", i.e:
System.out.println("Setting plot to screen...");
ImageIcon icon2 = new ImageIcon("inplot.png");
String msgTitle = "";
String msgCaption = "Wavelength in nm";
JOptionPane.showMessageDialog(null, msgCaption, msgTitle, JOptionPane.INFORMATION_MESSAGE, icon2);
I'm working in Netbeans 8 on Windows 8.1.
Why is the system remembering the image from the previous run, and how can I stop this?
Many thanks, and apologies for the length of the code, I didn't want to leave anything out that might be causing this issue. If I can improve the question in any way, please let me know so that I can prevent myself from being blocked!
The preferred solution would be to use ImageIO.read
over ImageIcon(String)
, but if you have to, you should call icon2.flush()
before attempting to reload it.
See Image#flush
and Reading/Loading Images for more details