I have been trying to add an image to all pages using itextsharp. The image needs to be OVER all content of every page. I have used the following code below all the otherdoc.add()
Document doc = new Document(iTextSharp.text.PageSize.A4, 10, 10, 30, 1);
PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream(Server.MapPath("~/pdf/" + fname), FileMode.Create));
doc.Open();
Image image = Image.GetInstance(Server.MapPath("~/images/draft.png"));
image.SetAbsolutePosition(12, 300);
writer.DirectContent.AddImage(image, false);
doc.Close();
The above code only inserts an image in the last page. Is there any way to insert the image in the same way in all pages?
It's normal that the image is only added once; after all: you're adding it only once. (Or you've left away some essential steps in your code snippet: see the edit I made.)
In any case: you can solve your problem by using a page event. There are some examples in Java here: http://itextpdf.com/sandbox/events
Or you can consult chapter 5 of my book. All examples are available in Java as well as in C#.
You should create a document in 5 steps and add an event in step 2:
// step 1
Document document = new Document();
// step 2
PdfWriter writer = PdfWriter.GetInstance(document, stream);
MyEvent event = new MyEvent();
writer.PageEvent = event;
// step 3
document.Open();
// step 4
// Add whatever content you want to add
// step 5
document.Close();
You have to write the MyEvent class yourself:
protected class MyEvent : PdfPageEventHelper {
Image image;
public override void OnOpenDocument(PdfWriter writer, Document document) {
image = Image.GetInstance(Server.MapPath("~/images/draft.png"));
image.SetAbsolutePosition(12, 300);
}
public override void OnEndPage(PdfWriter writer, Document document) {
writer.DirectContent.AddImage(image);
}
}
The OnEndPage() in class MyEvent will be triggered every time the PdfWriter has finished a page. Hence the image will be added on every page.
Caveat: it is important to create the image object outside the OnEndPage() method, otherwise the image bytes risk being added as many times as there are pages in your PDF (leading to a bloated PDF).
Document document = new Document();
// step 2
PdfWriter writer = PdfWriter.GetInstance(document, stream);
final MyEvent event = new MyEvent();
writer.setPageEvent(event);
document.Open();
// Add whatever content you want to add
document.Close();
//Now Create The new class and override the onEndPage()
//I have used this for footer image but you can add wherever you want
//in the whole page using setAbsolutePosition(see below the class)
//I am using palyFramework with java
package controllers;
import java.io.IOException;
import java.nio.file.Files;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfWriter;
import play.Play;
public class MyEvent extends PdfPageEventHelper{
#Override
public void onEndPage(final PdfWriter writer, final Document document)
{
final Font ffont = new Font(Font.FontFamily.TIMES_ROMAN,8,
Font.ITALIC);
Image img;
try {
final Phrase footer = new Phrase("Powered By :", ffont);
img=Image.getInstance(Files.readAllBytes(Play.application().getFile("/
img- path/Image.png").toPath()));
img.scaleToFit(60f, 40f);
img.setAbsolutePosition(510,5);
final PdfContentByte cb = writer.getDirectContent();
cb.addImage(img);
ColumnText.showTextAligned(cb, Element.ALIGN_CENTER,
footer,490, 15, 0);
} catch (IOException | DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}}
It works fine for me; refer to this link.
Related
I am using iText 5. I am following the example found here:
https://web.archive.org/web/20150816002422/http://itextpdf.com/sandbox/tables/ListInCell
/**
* This example was written by Bruno Lowagie for a prospective customer.
* The code in this sample works with the latest version of iText.
* It doesn't work with versions predating iText 5.
*/
package sandbox.tables;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.List;
import com.itextpdf.text.ListItem;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
public class ListInCell {
public static final String DEST = "results/tables/list_in_cell.pdf";
public static void main(String[] args) throws IOException, DocumentException {
File file = new File(DEST);
file.getParentFile().mkdirs();
new ListInCell().createPdf(DEST);
}
public void createPdf(String dest) throws IOException, DocumentException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
// This is how not to do it (but it works anyway):
// We create a list:
List list = new List();
list.add(new ListItem("Item 1"));
list.add(new ListItem("Item 2"));
list.add(new ListItem("Item 3"));
// We wrap this list in a phrase:
Phrase phrase = new Phrase();
phrase.add(list);
// We add this phrase to a cell
PdfPCell phraseCell = new PdfPCell();
phraseCell.addElement(phrase);
// We add the cell to a table:
PdfPTable phraseTable = new PdfPTable(2);
phraseTable.setSpacingBefore(5);
phraseTable.addCell("List wrapped in a phrase:");
phraseTable.addCell(phraseCell);
// We wrap the phrase table in another table:
Phrase phraseTableWrapper = new Phrase();
phraseTableWrapper.add(phraseTable);
// We add these nested tables to the document:
document.add(new Paragraph("A list, wrapped in a phrase, wrapped in a cell, wrapped in a table, wrapped in a phrase:"));
document.add(phraseTableWrapper);
// This is how to do it:
// We add the list directly to a cell:
PdfPCell cell = new PdfPCell();
cell.addElement(list);
// We add the cell to the table:
PdfPTable table = new PdfPTable(2);
table.setSpacingBefore(5);
table.addCell("List placed directly into cell");
table.addCell(cell);
// We add the table to the document:
document.add(new Paragraph("A list, wrapped in a cell, wrapped in a table:"));
document.add(table);
// Avoid adding tables to phrase (but it works anyway):
Phrase tableWrapper = new Phrase();
tableWrapper.add(table);document.add(new Paragraph("A list, wrapped in a cell, wrapped in a table, wrapped in a phrase:"));
document.add(tableWrapper);
document.close();
}
}
...and it gives a result similar to the sample PDF found here:
https://web.archive.org/web/20140308004615/http://itextpdf.com/sites/default/files/list_in_cell.pdf
My issue is this: you can see that the text in each of the left cells ("list wrapped in a phrase...") is not lined-up horizontally with the first item of each list ("Item 1"). Specifically, I want to move up the text in the right cell's list. How do I do that?
Set cell.PaddingTop = -3f; to move it up a little bit.
I am trying to do the following using itext and java through eclipse.I need to create a PDF which will consist of a no of multiple choice questions retrieved from database.The data retrieved is in the form of html tags hence for that i am using xml worker to parse it.I am able to retrieve the questions one by one from the database and add it to the pdf.But the problem is that it occupies only one side of a page while i need the questions to cover 2 columns of a page.
When the end of the first PDF page is reached it should utilize the right hand corner of the first PDF page to add questions.Only when both left and right sides of a page are fully used it should move on to the next PDF page.
Now i managed to get the html data in 2 columns using ColumnText.But the problem i face now is that the questions retrieved from database do not appear in the format as intended.Each question is getting displayed on one line.
I entered the questions is this format:
1)What is 2+2=?
a)2
b)4
c)8
d)15
I want that the output on pdf should be as above.
However i get the following as output:
1)What is2+2=?a)2b)4c)8d)15
How do i preserve the html formatting ?????????
This is my code so far:
import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.List;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.draw.LineSeparator;
import com.itextpdf.tool.xml.ElementHandler;
import com.itextpdf.tool.xml.ElementList;
import com.itextpdf.tool.xml.Pipeline;
import com.itextpdf.tool.xml.Writable;
import com.itextpdf.tool.xml.XMLWorker;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.itextpdf.tool.xml.html.Tags;
import com.itextpdf.tool.xml.parser.XMLParser;
import com.itextpdf.tool.xml.pipeline.WritableElement;
import com.itextpdf.tool.xml.pipeline.css.CSSResolver;
import com.itextpdf.tool.xml.pipeline.css.CssResolverPipeline;
import com.itextpdf.tool.xml.pipeline.end.PdfWriterPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;
public class ColumnTextExample {
public static final float[][] COLUMNS = {
{ 36, 36, 224, 579 } , { 230, 36, 418, 579 }
};
public static void main(String[] args)throws IOException, DocumentException, ClassNotFoundException, SQLException {
// TODO Auto-generated method stub
Document document = new Document(PageSize.A4.rotate());
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("C:\\columns.pdf"));
document.open();
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test3", "root", "root");
Statement st=con.createStatement();
ResultSet rs=st.executeQuery("select * from exam2");
int size=0;
while (rs.next()){
size++;
};
ResultSet rs1=st.executeQuery("select * from exam2");
String[] myStringArray = new String[size];
int i=0;
while (rs1.next()){
myStringArray[i]=rs1.getString("paper");
i++;
}
ColumnText ct = new ColumnText(writer.getDirectContent());
for (String article : myStringArray) {
ct.addElement(createPhrase(article,writer,document));
ct.addElement(Chunk.NEWLINE);
document.add(Chunk.NEWLINE);
}
ct.setAlignment(Element.ALIGN_CENTER);
ct.setExtraParagraphSpace(55);
ct.setLeading(0, 1.2f);
ct.setFollowingIndent(27);
int linesWritten = 0;
int column = 0;
int status = ColumnText.START_COLUMN;
while (ColumnText.hasMoreText(status)) {
ct.setSimpleColumn(
COLUMNS[column][0], COLUMNS[column][1],
COLUMNS[column][2], COLUMNS[column][3]);
ct.setYLine(COLUMNS[column][3]);
status = ct.go();
linesWritten += ct.getLinesWritten();
column = Math.abs(column - 1);
if (column == 0)
document.newPage();
}
ct.addElement(new Phrase("Lines written: " + linesWritten));
ct.go();
document.close();
}
public static Phrase createPhrase(String myString, PdfWriter writer, Document document) throws IOException, DocumentException {
Phrase p = new Phrase();
String myString2=myString+"<html><body><br></br></body></html>";
String k="<br></br>";
XMLWorkerHelper xwh = XMLWorkerHelper.getInstance();
InputStream is = new ByteArrayInputStream(myString.getBytes());
ElementList myList = new ElementList();
ElementList myList1 = new ElementList();
xwh.parseXHtml(myList,new StringReader(myString2));
p.addAll(myList);
return p;
}
}
When i use XMLWorkerHelper.getInstance().parseXHtml(writer, document, new StringReader(name1)); i am able to preserve the html formatting such as new line.
The below code helps me retrieve html data from DB and parse it while preserving the formatting.However it prints to the pdf in a single column
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.StringReader;
import com.itextpdf.text.Document;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import java.io.ByteArrayInputStream;
import java.sql.*;
public class GeneratePDF {
public static void main(String[] args) {
try {
OutputStream file = new FileOutputStream(new File("C:\\Test.pdf"));
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, file);
document.open();
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test3", "root", "root");
Statement st=con.createStatement();
ResultSet rs=st.executeQuery("select paper from exam2 ");
String name1="";
while (rs.next()){
String name = rs.getString("paper");
//out.println(name);
name1=name;
/*String k="<h1 style='text-align: center;'><strong>Maths Question2 Paper</strong></h1>"+
"<pre><strong>1)What is the sum of 2+2??<br /></strong><strong>a)3<br /></strong><strong>b)5<br /></strong><strong>c)4<br /></strong><strong>d)1</strong></pre>"+
"<pre><strong>2)What is the sum of 5+2??<br /></strong><strong>a)3<br />b)5<br />c)7<br />d)1</strong></pre>"+
"<pre> </pre>";*/
System.out.println(name1);
//InputStream is = new ByteArrayInputStream(name1.getBytes());
XMLWorkerHelper.getInstance().parseXHtml(writer, document, new StringReader(name1));
}
document.close();
file.close();
} catch (Exception e) {
e.printStackTrace();
}}}
You're parsing the HTML to a Document. This means you want iText to organize all content on one page, using one column defined by the page size (in your case A4) and the page margins (in your case 36pt on each side).
If you want to organize the content differently, you should use the parseXHTML() method that takes an ElementHandler as parameter and pass an ElementList object. This list will then contain a List of Element objects that you can feed to a ColumnText object. With the ColumnText class, you can define multiple rectangles on a page, and use the go() method to fill these rectangles with the content from the ElementList.
I need to put a hyperlink at the footer of my PDF generated using iTextSharp.
I know how to use PdfPageEventHelper to print some text in the footer but not putting a hyperlink.
public class PdfHandlerEvents: PdfPageEventHelper
{
private PdfContentByte _cb;
private BaseFont _bf;
public override void OnOpenDocument(PdfWriter writer, Document document)
{
_cb = writer.DirectContent;
}
public override void OnEndPage(PdfWriter writer, Document document)
{
base.OnEndPage(writer, document);
_bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
Rectangle pageSize = document.PageSize;
_cb.SetRGBColorFill(100, 100, 100);
_cb.BeginText();
_cb.SetFontAndSize(_bf, 10);
_cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "More information", pageSize.GetRight(200), pageSize.GetBottom(30), 0);
_cb.EndText();
}
}
How do I make the text "More information" a hyperlink?
Edited:
After the answer from Chris below, I have also figure out how to print image at the footer, here is the code:
Image pic = Image.GetInstance(#"C:\someimage.jpg");
pic.SetAbsolutePosition(0, 0);
pic.ScalePercent(25);
PdfTemplate tpl = _cb.CreateTemplate(pic.Width, pic.Height);
tpl.AddImage(pic);
_cb.AddTemplate(tpl, 0, 0);
The Document object generally lets you work with abstract things like Paragraph and Chunk but in doing so you lose absolute positioning. The PdfWriter and PdfContentByte objects give you absolute positioning but you need to work with lower level objects like raw text.
Luckily there is a happy middle-ground object called ColumnText that should do what you're looking for. You can think of the ColumnText as basically a table and most people use it as a single column table so you can actually just think of it as a rectangle that you add objects to. See the comments in the code below for any questions.
public class PdfHandlerEvents : PdfPageEventHelper {
private PdfContentByte _cb;
private BaseFont _bf;
public override void OnOpenDocument(PdfWriter writer, Document document) {
_cb = writer.DirectContent;
}
public override void OnEndPage(PdfWriter writer, Document document) {
base.OnEndPage(writer, document);
_bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
iTextSharp.text.Rectangle pageSize = document.PageSize;
//Create our ColumnText bound to the canvas
var ct = new ColumnText(_cb);
//Set the dimensions of our "box"
ct.SetSimpleColumn(pageSize.GetRight(200), pageSize.GetBottom(30), pageSize.Right, pageSize.Bottom);
//Create a new chunk with our text and font
var c = new Chunk("More Information", new iTextSharp.text.Font(_bf, 10));
//Set the chunk's action to a remote URL
c.SetAction(new PdfAction("http://www.aol.com"));
//Add the chunk to the ColumnText
ct.AddElement(c);
//Tell the ColumnText to draw itself
ct.Go();
}
}
I'm working on a JFrame interface to interact easily with a large amount of data. The data is saved in a .txt file, and when a name is selected from the JList, my program reads the appropriate lines of data, converts them into an Object I've defined (CounterParty), and displays the appropriate fields of the objects in JLabels. This all works well. I've also written code to launch a new JPanel that edits the selected Object. The JPanel opens, already populated with the data, and when a button is clicked the existing information on the .txt file is deleted and replaced with the new, edited data. This also works well.
However, I would like to make this a bit more user-friendly. I want the JLabels where the information is initially displayed to convert into JTextFields populated with the data from the jLabels when the Edit button is clicked. This would remove needing to launch the new JPanel window altogether. I assume is would change the visibility to false of the JLabels and create new JTextField objects. I'm having trouble with this. Can JLabel objects be converted to JTextFields? Can I maybe have both objects in the exact same spot, but alternate visibility? I'm not sure how to go about this.
I'm using NetBeans.
Thank you for your help! Let me know if any additional information is needed.
This is one way to do that:
Assuming that JLabel is your label and textfield your JTextField
textfield = new JTextField(label.getText());
This will create a with the text of the JLabel.
You should place your JLabel in a dedicated JPanel, so you remove the JLabel from it and replace it with the JTextField, then repaint()/revalidate()
I created a small example which I think demonstrates what you want. It uses a button which when pressed will either remove the JTextField and add the JLabel and vice versa and then it will call revalidate() and repaint() to show changes to the frame after each button click:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class JLabelToJTextField extends JFrame {
JLabel jLabel;
JTextField jTextField;
JButton jButton;
JPanel mainPanel;
public JLabelToJTextField() {
jLabel = new JLabel("Name");
jTextField = new JTextField(15);
jButton = new JButton("Edit");
mainPanel = new JPanel(new BorderLayout());
createUI();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new JLabelToJTextField().setVisible(true);
}
});
}
private void createUI() {
setTitle("JLabel to JtextField");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addComponentsToPanel();
setLocationRelativeTo(null);
pack();
}
private void addComponentsToPanel() {
mainPanel.add(jLabel, BorderLayout.CENTER);
mainPanel.add(jButton, BorderLayout.SOUTH);
addActionListeners();
getContentPane().add(mainPanel);
}
private void addActionListeners() {
jButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
switch (jButton.getText()) {
case "Edit":
mainPanel.remove(jLabel);//remove component
mainPanel.add(jTextField, BorderLayout.CENTER);//add new component
jButton.setText("Done");
//refresh JFrame
revalidate();
repaint();
break;
case "Done":
mainPanel.remove(jTextField);//remove component
mainPanel.add(jLabel, BorderLayout.CENTER);//add new component
jButton.setText("Edit");//set button text to original
//refresh JFrame
revalidate();
repaint();
break;
}
}
});
}
}
I am trying to do a tutorial that allows one to Add and Remove stocks and witness their price and change. This tutorial demonstrates how to use the GUI builder, GWT Designer, to create and design a Stock Watcher application based on the GWT tutorial.
http://code.google.com/webtoolkit/tools/gwtdesigner/tutorials/stockwatcher.html#design_ui
So far I have SW.java:
package edu.gatech.client;
import java.util.ArrayList;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class SW implements EntryPoint {
private RootPanel rootPanel;
private FlexTable stocksFlexTable;
private HorizontalPanel addPanel;
private VerticalPanel mainWindow;
private TextBox newSymbolTextBox;
private Button addButton;
private Label lastUpdatedLabel;
private ArrayList <String> stocks = new ArrayList<String>(); //Add this line
public void onModuleLoad() {
rootPanel = RootPanel.get();
mainWindow = new VerticalPanel();
rootPanel.add(mainWindow, 10, 10);
mainWindow.setSize("267px", "175px");
FlexTable stocksFlexTable = new FlexTable();
//Add these lines
stocksFlexTable.setText(0, 0, "Symbol");
stocksFlexTable.setText(0, 1, "Price");
stocksFlexTable.setText(0, 2, "Change");
stocksFlexTable.setText(0, 3, "Remove");
mainWindow.add(stocksFlexTable);
addPanel = new HorizontalPanel();
rootPanel.add(addPanel, 10, 200);
addPanel.setSize("267px", "68px");
newSymbolTextBox = new TextBox();
newSymbolTextBox.addKeyPressHandler(new KeyPressHandler() {
public void onKeyPress(KeyPressEvent event) {
if (event.getCharCode() == KeyCodes.KEY_ENTER){
addStock();
}
}
});
addPanel.add(newSymbolTextBox);
newSymbolTextBox.setWidth("211px");
addButton = new Button("Add");
addButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
addStock();
}
});
addPanel.add(addButton);
lastUpdatedLabel = new Label("New Label");
rootPanel.add(lastUpdatedLabel, 48, 274);
}
private void addStock() {
final String symbol = newSymbolTextBox.getText().toUpperCase().trim();
newSymbolTextBox.setFocus(true);
// Stock code must be between 1 and 10 chars that are numbers, letters, or dots.
if (!symbol.matches("^[0-9A-Z\\.]{1,10}$")) {
Window.alert("'" + symbol + "' is not a valid symbol.");
newSymbolTextBox.selectAll();
return;
}
newSymbolTextBox.setText("");
// don't add the stock if it's already in the watch list
if (stocks.contains(symbol))
return;
// add the stock to the list
int row = stocksFlexTable.getRowCount();
stocks.add(symbol);
stocksFlexTable.setText(row, 0, symbol);
// add button to remove this stock from the list
Button removeStock = new Button("x");
removeStock.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
int removedIndex = stocks.indexOf(symbol);
stocks.remove(removedIndex);
stocksFlexTable.removeRow(removedIndex + 1);
}
});
stocksFlexTable.setWidget(row, 3, removeStock);
}
}
When I run the web application, I cannot Add a stock. The program does, however, distinguish between bad stock names and acceptable ones. Instead I get an "uncaught exception escaped" error and the program doesn't really do anything. How do I troubleshoot this?
Use the debugger and single step through the code. Set a breakpoint on addStock's first line and find which line crashes. Once you find which line you then instrument the line to find out what aspect is causing the problem - assuming you can't deduce the problem by looking at the line.