I'm using Apache's PDFBox version 2.0.4 and am having a problem using lineTo and curveTo. My function takes parameters of radians, starting degrees and ending degrees and then uses lineTo and curveTo to generate a slice of a pie chart.
mContents.setNonStrokingColor(color);
mContents.moveTo(0, 0);
List<Float> smallArc = createSmallArc(rad, Math.toRadians(startDeg), Math.toRadians(endDeg));
mContents.lineTo(smallArc.get(0), smallArc.get(1));
mContents.curveTo(smallArc.get(2), smallArc.get(3), smallArc.get(4), smallArc.get(5), smallArc.get(6), smallArc.get(7));
mContents.closePath();
mContents.fill();
The pie chart generates and appears to be fine. My app adds a footer which contains a logo that it reads from a file as follows:
try {
pdImage = PDImageXObject.createFromFile(mFullImagePath, mDoc);
}catch(IOException ie){System.out.println("Error opening image file - "+ie.getMessage());}
try {
mContents.drawImage(pdImage,250,5,pdImage.getWidth()/2,pdImage.getHeight()/2);
}catch(IOException e){System.out.println("Error adding image file - "+ e.getMessage());}
When the pi chart is included in the pdf generated, the footer and image are not in the pdf. Stubbing the code to generate the pie chart and the footer shows up with the image included.
Currently have to add the pie chart specifying specific coordinates after the page has been generated otherwise the additional lines below the pie chart do not appear.
Could the curveTo and lineTo generated output be bigger than what is displayed causing these issues?
EDIT - adding the image in the footer before drawing the graph and the image, graph and text all appear.
Appreciate any pointers
Complete code:
import com.google.code.geocoder.Geocoder;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.util.Matrix;
import org.apache.tomcat.jni.Address;
import org.slf4j.Logger;
import java.awt.*;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
/** * Created by tim on 7/6/2017. */
public class ReportDataPDFBox {
private PDDocument mDoc = null;
private PDPage mPage = null;
private PDImageXObject pdImage = null;
private PDFont mHeaderFont = PDType1Font.HELVETICA_BOLD;
private final int FONT_SIZE_HDR1 = 16;
private final int FONT_SIZE_HDR2 = 14;
private final int FONT_SIZE_REG = 12;
private final int HDR_INDENT = 30;
private final int BODY_INDENT_1 = 55;
private final int BODY_INDENT_2 = 65;
private final int BODY_INDENT_3 = 75;
private PDFont mRegFont = PDType1Font.HELVETICA;
PDPageContentStream mContents = null;
private String mReportName = null;
private String mFullImagePath = null;
private String mMonth = null;
private boolean mReportDone = true;
private int mHorizonVal = 700;
private int mHorizonGrph = 0;
private long[] mDayPercent;
private Calendar mCurrentCalendar = null;
ProcessFrequencyData pfd = null;
ProcessWeatherData pwd = null;
ProcessPerformanceData ppd = null;
Logger log = null;
Color[] mColor = {Color.PINK,Color.YELLOW,Color.CYAN, Color.BLUE,Color.RED,Color.GREEN,Color.ORANGE,Color.LIGHT_GRAY};
public ReportDataPDFBox(Logger logger, ProcessFrequencyData pfd, ProcessWeatherData pwd, ProcessPerformanceData ppd){
this.log = logger;
this.pfd = pfd;
this.pwd = pwd;
this.ppd = ppd;
initializeDoc();
}
public void initializeDoc(){
mDoc = new PDDocument();
mPage = new PDPage();
mDoc.addPage(mPage);
mFullImagePath = "logo.png";
mCurrentCalendar = Calendar.getInstance();
mMonth = mCurrentCalendar.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault());
mReportName = mMonth + ".pdf";
try{
mContents = new PDPageContentStream(mDoc, mPage);
}catch(IOException e){System.out.println("Error setting content stream - "+e.getLocalizedMessage());}
}
public boolean writeTheReport(){
addHeader();
addFooter();
generateReportContent();
// addFooter();
cleanUpALlDone();
return mReportDone;
}
private void addHeader(){
try {
mContents.beginText();
mContents.setFont(mHeaderFont,FONT_SIZE_HDR1);
mContents.newLineAtOffset(200, 740);
mContents.showText(mMonth + " - ActoTracker Report - " + mCurrentCalendar.get(Calendar.YEAR));
mContents.endText();
}catch (IOException io){System.out.println("Error with text content screen");}
}
private void generateReportContent(){
addNumberRunInfo();
addLocationRunInfo();
addWeekDayInfo();
addWeekInfo();
addFrequencyData();
pukeMeAChart();
// generateDailyChart();
}
private void addNumberRunInfo(){
int daysActive = Utility.getDaysBetweenDates(Utility.getOldestDate(pfd.getFirstDate(),
pwd.getFirstDate()), Calendar.getInstance().getTimeInMillis());
writeLine(mHeaderFont, FONT_SIZE_HDR2,HDR_INDENT, "Frequency Information");
long percentActiveIdle = (pfd.getTotalDaysRun()*100/daysActive);
String line = "Number of Runs - " + pfd.getTotalDaysRun() + " Number of days ActoTracker active - " + daysActive + " Percent run =
"+percentActiveIdle;
writeLine(mRegFont, FONT_SIZE_REG, BODY_INDENT_1, line);
}
private void addLocationRunInfo(){
String line = "Number of locations run = " + pfd.getLocationRun();
writeLine(mRegFont,FONT_SIZE_REG,BODY_INDENT_1,line);
for (int i=1; i<=pfd.getLocationRun();i++){
String[] locationInfo = pfd.getLocationInfo(i);
long percent = pfd.getRunsByLocation(i)*100/pfd.getTotalDaysRun();
String line2= new String( locationInfo[0] + " - " + locationInfo[1] +" , "+locationInfo[2]+ " Number of runs = " +
pfd.getRunsByLocation(i) + " Percent of runs = " +percent );
writeLine(mRegFont, FONT_SIZE_REG,BODY_INDENT_2,line2);
}
}
private void addWeekDayInfo(){
int totDaysRunning = pfd.getTotalRunDay();
int leastCnt = 0;
int mostCnt = 0;
mHorizonGrph = mHorizonVal - 90;
mDayPercent = new long[8];
String mostDay = " most common day";
String leastDay = " least common day";
DayFrequencyResults frequency = pfd.getDayDistribution();
int[] leastDays = frequency.getLessDays();
int[] mostDays = frequency.getMostDays();
StringBuilder leastString = new StringBuilder();
StringBuilder mostString = new StringBuilder();
for (int i=0; i< leastDays.length;i++){
if (leastDays[i] != 0) {
leastString.append(Utility.getDayName(leastDays[i])).append(" ");
leastCnt++;
}
}
for (int j=0; j< mostDays.length;j++){
if (mostDays[j] != 0) {
mostString.append(Utility.getDayName(j+1)).append(" ");
mostCnt++;
}
}
if (leastCnt > 1){leastDay += "s";}
if (mostCnt > 1) {mostDay +="s";}
String line = mostString.toString()+mostDay+ " to run"+ " "+leastString.toString()+leastDay+" to run";
writeLine(mRegFont,FONT_SIZE_REG,BODY_INDENT_1,line);
for (int i=1;i<8;i++){
String day = new String(Utility.getDayName(i)+" " + pfd.getRweekDayCount(i) + " runs "+"
"+pfd.getRweekDayCount(i)*100/totDaysRunning)+ "%";
writeLine(mRegFont,FONT_SIZE_REG,BODY_INDENT_2,day);
double x = pfd.getRweekDayCount(i) / (double)pfd.getTotalDaysRun();
mDayPercent[i] = Math.round(360*x);
}
System.out.println("BreakPoint");
}
private void addWeekInfo(){
String line;
Integer[] largestWeekTotals = {0,0,0,0,0,0,0};
double largestDistance = 0D;
double firstHalfDist = 0D;
double secondHalfDist = 0D;
DecimalFormat df = new DecimalFormat("####.##");
int[] distFreq = pfd.getMonthlySummaryInfo();
if (distFreq[0] > distFreq[1]){
line = "Ran more in first half of months run. "+ distFreq[0] + " times versus "+ distFreq[1]+" times";
}else{
line = "Ran more in second half of months run. " + distFreq[1] + " times versus " + distFreq[0]+" times";
}
writeLine(mRegFont,FONT_SIZE_REG, BODY_INDENT_1, line);
for (int i = 1; i<7;i++){
if (i<4){
firstHalfDist += Utility.getMileage(pfd.fa.getWeekDistanceTotal(i),false);
}else{
secondHalfDist += Utility.getMileage(pfd.fa.getWeekDistanceTotal(i),false);
}
}
if (firstHalfDist > secondHalfDist){
line = new String ("Ran further in the first half of the month " + df.format(firstHalfDist) + " miles versus " +
df.format(secondHalfDist) + " miles");
}else{
line = new String ("Ran further in the second half of the month " + df.format(secondHalfDist) + " miles versus " +
df.format(firstHalfDist)+ " miles");
}
writeLine(mRegFont,FONT_SIZE_REG,BODY_INDENT_1, line);
}
private void addFrequencyData(){
int greatestFreq = 0;
int leastDiff = 0;
int greatestDiff = 0;
int leastFreq = 0;
for (int i=0; i<30; i++){
int cnt = ppd.getRunsByFrequentcy(i);
if (cnt > greatestFreq){
greatestFreq = cnt;
greatestDiff = i;
}
else{
if (cnt > 0 && i>leastDiff){
leastDiff = i;
leastFreq = cnt;
}
}
log.info("Frequency?? = " + cnt + " index = "+i);
}
String line = greatestDiff + " days is the most common frequency between runs "+greatestFreq+" times";
writeLine(mRegFont,FONT_SIZE_REG,BODY_INDENT_1,line);
String line2 = leastDiff + " days longest time between runs " + leastFreq + " times";
writeLine(mRegFont,FONT_SIZE_REG,BODY_INDENT_1,line2);
}
private void writeLine(PDFont font, int fontSize, int indent, String text){
mHorizonVal -= 20;
try {
mContents.beginText();
mContents.setFont(font, fontSize);
mContents.newLineAtOffset(indent,mHorizonVal);
mContents.showText(text);
mContents.endText();
}catch(IOException e){}
}
private void addFooter(){
log.info("IN addFooter");
mPage = new PDPage();
mDoc.addPage(mPage);
try {
pdImage = PDImageXObject.createFromFile(mFullImagePath, mDoc);
}catch(IOException ie){System.out.println("Error opening image file - "+ie.getMessage());}
try {
mContents.drawImage(pdImage,250,5,pdImage.getWidth()/2,pdImage.getHeight()/2);
}catch(IOException e){log.error("Error adding image file - "+ e.getLocalizedMessage());}
}
private void cleanUpALlDone(){
try {
mContents.close();
mDoc.save(mReportName);
mDoc.close();
}catch (IOException ie){System.out.println("Error closing PDF document - " + ie.getMessage());}
}
private void generateDailyChart(){
int totalVal = 0;
try {
mContents.transform(Matrix.getTranslateInstance(375, 525));
}catch(IOException e){}
for (int i=1; i< 8;i++){
totalVal += mDayPercent[i];
writeTheChart(mDayPercent[i-1], totalVal,mColor[i]);
log.info("Color selected = " +mColor[i] +"Index = "+i);
}
}
private void writeTheChart(long beg, long end, Color color){
try {
log.info("Color received = " + color);
drawSlice(color, 60,beg, end);
}catch(IOException e){}
}
private void pukeMeAChart(){
try {
mContents.transform(Matrix.getTranslateInstance(375,525));
drawSlice(Color.YELLOW, 60, 0, 69);
mContents.fill();
drawSlice(Color.BLUE, 60, 69, 117);
drawSlice(Color.RED, 60, 117, 181);
mContents.fill();
drawSlice(Color.WHITE, 60, 181, 208);
mContents.fill();
drawSlice(Color.GREEN, 60, 208, 272);
mContents.fill();
drawSlice(Color.YELLOW, 60, 272, 336);
drawSlice(Color.BLUE, 60, 336, 360);
mContents.fill();
} catch(IOException e ){}
}
private void drawSlice(Color color, float rad, float startDeg, float endDeg) throws IOException
{
mContents.setNonStrokingColor(color);
mContents.moveTo(0, 0);
List<Float> smallArc = createSmallArc(rad, Math.toRadians(startDeg), Math.toRadians(endDeg));
mContents.lineTo(smallArc.get(0), smallArc.get(1));
mContents.curveTo(smallArc.get(2), smallArc.get(3), smallArc.get(4), smallArc.get(5), smallArc.get(6), smallArc.get(7));
mContents.closePath();
mContents.fill();
}
private List<Float> createSmallArc(double r, double a1, double a2)
{
// Compute all four points for an arc that subtends the same total angle
// but is centered on the X-axis
double a = (a2 - a1) / 2;
double x4 = r * Math.cos(a);
double y4 = r * Math.sin(a);
double x1 = x4;
double y1 = -y4;
double q1 = x1*x1 + y1*y1;
double q2 = q1 + x1*x4 + y1*y4;
double k2 = 4/3d * (Math.sqrt(2 * q1 * q2) - q2) / (x1 * y4 - y1 * x4);
double x2 = x1 - k2 * y1;
double y2 = y1 + k2 * x1;
double x3 = x2;
double y3 = -y2;
// Find the arc points' actual locations by computing x1,y1 and x4,y4
// and rotating the control points by a + a1
double ar = a + a1;
double cos_ar = Math.cos(ar);
double sin_ar = Math.sin(ar);
List<Float> list = new ArrayList<Float>();
list.add((float) (r * Math.cos(a1)));
list.add((float) (r * Math.sin(a1)));
list.add((float) (x2 * cos_ar - y2 * sin_ar));
list.add((float) (x2 * sin_ar + y2 * cos_ar));
list.add((float) (x3 * cos_ar - y3 * sin_ar));
list.add((float) (x3 * sin_ar + y3 * cos_ar));
list.add((float) (r * Math.cos(a2)));
list.add((float) (r * Math.sin(a2)));
return list;
}
}
In contrast to your assumption, you are not having a problem using lineTo and curveTo, i.e. your method drawSlice. You are having problems in the code using that method, i.e. here:
private void pukeMeAChart(){
try {
mContents.transform(Matrix.getTranslateInstance(375,525));
drawSlice(Color.YELLOW, 60, 0, 69);
mContents.fill();
drawSlice(Color.BLUE, 60, 69, 117);
drawSlice(Color.RED, 60, 117, 181);
mContents.fill();
drawSlice(Color.WHITE, 60, 181, 208);
mContents.fill();
drawSlice(Color.GREEN, 60, 208, 272);
mContents.fill();
drawSlice(Color.YELLOW, 60, 272, 336);
drawSlice(Color.BLUE, 60, 336, 360);
mContents.fill();
} catch(IOException e ){}
}
This method starts by translating the coordinate system
mContents.transform(Matrix.getTranslateInstance(375,525));
and does not undo that translation when it is finished. Thus, the footer and image are in the pdf, merely not where you would expect them but instead translated, probably outside the crop box.
To undo the translation (and other changes, too, like the fill color), simply store the graphics state at the start of pukeMeAChart and restore it at the end of it.
Furthermore, drawSlice fills the slice itself, so there is no path to fill in pukeMeAChart anymore. Thus, the fill calls there are invalid.
All changes applied:
private void pukeMeAChart(){
try {
mContents.saveGraphicsState();
mContents.transform(Matrix.getTranslateInstance(375,525));
drawSlice(Color.YELLOW, 60, 0, 69);
drawSlice(Color.BLUE, 60, 69, 117);
drawSlice(Color.RED, 60, 117, 181);
drawSlice(Color.WHITE, 60, 181, 208);
drawSlice(Color.GREEN, 60, 208, 272);
drawSlice(Color.YELLOW, 60, 272, 336);
drawSlice(Color.BLUE, 60, 336, 360);
mContents.restoreGraphicsState();
} catch(IOException e ){}
}
generateDailyChart(), another method (indirectly) using the drawSlice method, also has the graphics state issue and has to be fixed similarly:
private void generateDailyChart(){
mContents.saveGraphicsState();
int totalVal = 0;
try {
mContents.transform(Matrix.getTranslateInstance(375, 525));
}catch(IOException e){}
for (int i=1; i< 8;i++){
totalVal += mDayPercent[i];
writeTheChart(mDayPercent[i-1], totalVal,mColor[i]);
log.info("Color selected = " +mColor[i] +"Index = "+i);
}
mContents.restoreGraphicsState();
}
As it currently is commented out and, therefore, not used, this problem does not show yet, though.
Related
Recently I have been working on a program that can convert TeX-generated PDFs to a certain form of text that retains some semantically meaningful style information such as subscripts and superscripts.
When debugging it seems that there might be something very unusual going on with the PDFTextStripper class.
Here is my TeXUtil class that does most of the work.
import com.google.common.base.CharMatcher;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Stack;
public class TeXUtil {
private Stack<SSStatus> ssstatus;
private boolean accentMode;
private String fs;
private boolean mathMode;
private SymbolDB db;
private Hashtable<String, String> maccDict;
float endY;//Positions
float endX;
float Y;
int height;//Height
//boolean test;
public TeXUtil() throws IOException {
ssstatus = new Stack<SSStatus>();
fs = "rm";
accentMode = false;//as in the state of being right after an accent
mathMode = false;
db = new SymbolDB();
maccDict = new Hashtable<String, String>();
maccDict.put("\\vec","\\vec");
maccDict.put("\\widehat","\\widehat");
maccDict.put("\\widetilde","\\widetilde");
maccDict.put("\\^","\\hat");
maccDict.put("\\v","\\check");
maccDict.put("\\u","\\breve");
maccDict.put("\\`","\\grave");
maccDict.put("\\~","\\tilde");
maccDict.put("\\=","\\bar");
maccDict.put("\\.","\\dot");
maccDict.put("\\","\\ddot");
maccDict.put("\\'","\\acute");
endY = 0;
endX = 0;
Y = 0;
height = 0;
//test = false;
System.out.println("TeXUtil initialized!");
}
private static String fontShortName(PDFont font) {
String[] segments = font.getName().split("\\+");
return segments[segments.length - 1];
}
private static int fontHeight(PDFont font) {
CharMatcher matcher = CharMatcher.inRange('0', '9');
return Integer.parseInt(matcher.retainFrom(fontShortName(font)));
}
private static String fontClass(PDFont font) {
CharMatcher matcher = CharMatcher.inRange('A', 'Z');
return (matcher.retainFrom(fontShortName(font))).toLowerCase();
}
private String textToTeX(String shortFontName, int code) throws JSONException {
JSONObject info = db.getInfo(shortFontName, code);
return info.getString("value");
}
public String fullTextToTeX(PDFont font, int code, float newEndX, float newY, float newEndY){
String shortFontName = fontClass(font);
try {
JSONObject info = db.getInfo(shortFontName, code);
String teXCode = info.getString("value");
StringBuilder preamble1 = new StringBuilder("");
StringBuilder preamble2 = new StringBuilder("");
StringBuilder postamble = new StringBuilder("");
boolean text = info.getBoolean("text");
boolean math = info.getBoolean("math");
boolean tacc = info.getBoolean("tacc");
boolean macc = info.getBoolean("macc");
String newFont = info.getString("font");
int newHeight = fontHeight(font);
//Font change, rm is seen as having no font
if (!newFont.equals(fs)) {
if (!fs.equals("rm"))
preamble1.insert(0, '}');
if (!newFont.equals("rm")) {
preamble2.append('\\');
preamble2.append(newFont);
preamble2.append('{');
}
preamble1.insert(0, " fs = " + fs + " nFs = " + newFont + "\n");
fs = newFont;
}
if (height == 0) {
//preamble2.append(" Meow! am = " + accentMode + " fs = " + fs + " mm = " + mathMode + "\n");
}
//Subscripts/Superscripts
if (height > newHeight && newEndX > endX) {//New subscript/superscript
if (newEndY < endY) {//New superscript
//ssstatus.push(SSStatus.SUP);
preamble2.insert(0, "^{");
}
else if (newY > Y) {//New subscript
//ssstatus.push(SSStatus.SUB);
preamble2.insert(0, "_{");
}
//else {
// System.out.println("Please investigate the situation: texcode = " + teXCode + "endY = " + endY + " Y=" + Y + " endX=" + endX + " newEndY=" + newEndY + " newY=" + newY + " newEndX= " + newEndX);
//}
}
else if (height < newHeight && height != 0) {
//ssstatus.pop();
preamble1.append('}');
}
height = newHeight;
endX = newEndX;
endY = newEndY;
Y = newY;
//Enter or leave math mode
if (mathMode && !math && !macc) {
mathMode = false;
preamble1.append('$');
}
else if (!mathMode && !text && !tacc) {
mathMode = true;
preamble2.insert(0,'$');
}
//Accents
if (accentMode) {//If accent mode is ever entered we need to leave it at once
postamble.append('}');
accentMode = false;
}
if ((mathMode && macc) || (!mathMode && tacc)) {//Right now assume that anything that can be an accent is an accent
postamble.append('{');
if (mathMode)
teXCode = maccDict.get(teXCode);
accentMode = true;
}
if (teXCode.charAt(0) == '\\')
return preamble1.toString() + preamble2.toString() + teXCode + ' ' + postamble.toString();
else
return preamble1.toString() + preamble2.toString() + teXCode + postamble.toString();
}
catch(JSONException e) {
return "\\" + shortFontName + "{" + code + "}";
}
}
}
Here is the main class.
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.TextPosition;
import com.google.common.base.CharMatcher;
import org.json.*;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Stack;
public class TEX2TXT {
public static void main(String args[]) throws IOException {
TeXUtil util = new TeXUtil();
//Loading an existing document
File file = new File("/Users/CatLover/Documents/Tex/Examples/c4.pdf");
PDDocument document = PDDocument.load(file);
//Instantiate PDFTextStripper class
PDFTextStripper pdfStripper = new PDFTextStripper() {
protected void writeString(String text, List<TextPosition> textPositions) throws IOException {
TeXUtil util = new TeXUtil();
StringBuilder builder = new StringBuilder();
for(TextPosition position: textPositions) {
float Y = position.getY();
float endY = position.getEndY();
float endX = position.getEndX();
PDFont font = position.getFont();
int[] codes = position.getCharacterCodes();
for(int code: codes) {
builder.append(util.fullTextToTeX(font, code, endX, Y, endY));
}
}
writeString(builder.toString());
}
};
//Retrieving text from PDF document
String text = pdfStripper.getText(document);
System.out.println(text);
//Closing the document
document.close();
}
What's really weird is that TeXUtil is constructed every time any white space between words appear while TeXUtil() should be called only once. I'm not sure why this is the case. Since the PDFs are produced by LaTeX and LaTeX does not put white space characters in PDFs but instead leave space between characters to implicitly represent white spaces this may affect how PDFBox works.
You're constructing a new TeXUtil in the first line of your PDFTextStripper subclass's writeString method. If you just remove that line, it should be able to still reference the util defined in your main method (though depending on the version of java you're using, you may have to make it final).
I am trying to detect faces and crop the face part in rectangular Image. I have done the face detection Part, but still not finding any help about how to crop the face part. Please have a look on my code..!
public class FaceDetect extends Activity {
private MyImageView mIV;
private Bitmap mFaceBitmap;
private int mFaceWidth = 200;
private int mFaceHeight = 200;
int cropXinit = 0;
int cropYint = 0;
int cropXend = 0;
int cropYend = 0;
Bitmap cropedBitmap;
Bitmap b;
private static final int MAX_FACES = 1;
private static String TAG = "FaceDetect";
private static boolean DEBUG = false;
protected static final int GUIUPDATE_SETFACE = 999;
protected Handler mHandler = new Handler() {
// #Override
public void handleMessage(Message msg) {
mIV.invalidate();
super.handleMessage(msg);
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mIV = new MyImageView(this);
setContentView(mIV, new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
// load the photo
b = ChooseActivity.bitmap;
mFaceBitmap = b.copy(Bitmap.Config.RGB_565, true);
b.recycle();
mFaceWidth = mFaceBitmap.getWidth();
mFaceHeight = mFaceBitmap.getHeight();
mIV.setImageBitmap(mFaceBitmap);
mIV.invalidate();
setFace();
}
public void setFace() {
FaceDetector fd;
FaceDetector.Face[] faces = new FaceDetector.Face[MAX_FACES];
PointF eyescenter = new PointF();
float eyesdist = 0.0f;
int[] fpx = null;
int[] fpy = null;
int count = 0;
try {
fd = new FaceDetector(mFaceWidth, mFaceHeight, MAX_FACES);
count = fd.findFaces(mFaceBitmap, faces);
} catch (Exception e) {
Log.e(TAG, "setFace(): " + e.toString());
return;
}
// check if we detect any faces
if (count > 0) {
fpx = new int[count * 2];
fpy = new int[count * 2];
for (int i = 0; i < count; i++) {
try {
faces[i].getMidPoint(eyescenter);
eyesdist = faces[i].eyesDistance();
// set up left eye location
fpx[2 * i] = (int) (eyescenter.x - eyesdist / 2);
fpy[2 * i] = (int) eyescenter.y;
// set up right eye location
fpx[2 * i + 1] = (int) (eyescenter.x + eyesdist / 2);
fpy[2 * i + 1] = (int) eyescenter.y;
if (DEBUG)
Log.e(TAG,
"setFace(): face "
+ i
+ ": confidence = "
+ faces[i].confidence()
+ ", eyes distance = "
+ faces[i].eyesDistance()
+ ", pose = ("
+ faces[i]
.pose(FaceDetector.Face.EULER_X)
+ ","
+ faces[i]
.pose(FaceDetector.Face.EULER_Y)
+ ","
+ faces[i]
.pose(FaceDetector.Face.EULER_Z)
+ ")" + ", eyes midpoint = ("
+ eyescenter.x + "," + eyescenter.y
+ ")");
} catch (Exception e) {
Log.e(TAG, "setFace(): face " + i + ": " + e.toString());
}
}
}
mIV.setDisplayPoints(fpx, fpy, count * 2, 1);
// if(eyescenter.x -eyesdist >= 0)
// {
// cropXinit = (int) (eyescenter.x -eyesdist) ;
// }
// else
// {
// cropXinit = 0;
// }
// if(eyescenter.x +eyesdist <= mFaceWidth)
// {
// cropXend = (int) (eyescenter.x +eyesdist) ;
// }
// else
// {
// cropXend = mFaceWidth;
// }
// if(eyescenter.y +eyesdist*2 <= mFaceHeight)
// {
// cropYend = (int) (eyescenter.y +eyesdist*2) ;
// }
// else
// {
// cropYend = mFaceHeight;
// }
// if(eyescenter.y -eyesdist >= 0)
// {
// cropYint = (int) (eyescenter.y -eyesdist) ;
// }
// else
// {
// cropYint = 0;
// }
// mIV.setImageBitmap(Bitmap.createBitmap(mFaceBitmap,cropXinit,cropYint,cropXend,cropYend));
}
}
createBitmap(Bitmap source, int x, int y, int width, int height) receives a start X and start Y, and a width and height value, not an end X and end Y. If you change your commented-out code to this it should work:
mIV.setImageBitmap(Bitmap.createBitmap(mFaceBitmap,cropXinit,cropYint,cropXend-cropXinit,cropYend-cropYinit));
So it's probably something wrong with my Flight class, but I can't figure out what exactly. I'm trying to display flight info, but only the airports are being shown when I run it (try Edinburgh -> Toronto). Here's my main class:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.StringTokenizer;
import org.jgrapht.alg.DijkstraShortestPath;
import org.jgrapht.graph.*;
public class FlightItinerary2
{
private static ArrayList<String[]> myEdges;
private static ArrayList<Flight> flight;
public FlightItinerary2()
{
} // ensure non-instantiability.
#SuppressWarnings("resource")
public static void main(String [] args)
{
// create a graph based on Strings
myEdges = new ArrayList<String[]>();
flight = new ArrayList<Flight>();
SimpleDirectedWeightedGraph<String, DefaultWeightedEdge> hrefGraph = createHrefGraph();
// note directed edges are printed as: (<v1>,<v2>)
//printAirports(hrefGraph);
//System.out.println(hrefGraph.toString());
Scanner sc = new Scanner(System.in);
System.out.println("\n Enter 1st airport");
String startVertex = sc.nextLine();
while(!hrefGraph.containsVertex(startVertex))
{
System.err.println("Please enter an existing airport.");
startVertex = sc.nextLine();
}
System.out.println("Enter 2nd airport");
String endVertex = sc.nextLine();
while(!hrefGraph.containsVertex(endVertex))
{
System.err.println("Please enter an existing airport.");
endVertex = sc.nextLine();
}
calculatePath(hrefGraph, startVertex, endVertex);
}
/**
* Creates a directed graph based on Strings that represents link
* structure.
*
* #return a graph based on Strings.
*/
private static SimpleDirectedWeightedGraph<String, DefaultWeightedEdge> createHrefGraph()
{
SimpleDirectedWeightedGraph<String, DefaultWeightedEdge> g =
(SimpleDirectedWeightedGraph<String, DefaultWeightedEdge>) new SimpleDirectedWeightedGraph<String, DefaultWeightedEdge>(DefaultWeightedEdge.class);
{
// add the vertices
g.addVertex("Edinburgh");
g.addVertex("Heathrow");
g.addVertex("Amsterdam");
g.addVertex("Boston");
g.addVertex("Chicago");
g.addVertex("Montreal");
g.addVertex("Toronto");
g.addVertex("New Delhi");
g.addVertex("Shanghai");
g.addVertex("Hong Kong");
// add edges to create linking structure
createTwoWayWeightedEdge(g, "Edinburgh", "Heathrow", 110);
generateFlight("1600", "1800", "BA445", 110);
generateFlight("0400", "0600", "BA452", 110);
createTwoWayWeightedEdge(g, "Heathrow", "Amsterdam", 100);
generateFlight("1400", "1600", "DC123", 100);
generateFlight("0400", "0600", "AB712", 100);
createTwoWayWeightedEdge(g, "Heathrow", "Boston", 230);
generateFlight("1800", "2200", "AD412", 230);
generateFlight("0900", "1300", "AA413", 230);
createTwoWayWeightedEdge(g, "Boston", "Chicago", 150);
generateFlight("0700", "1000", "BA178", 150);
generateFlight("1300", "1600", "YU712", 150);
createTwoWayWeightedEdge(g, "Boston", "Montreal", 100);
generateFlight("1600", "1900", "AG102", 100);
generateFlight("2100", "2300", "AH140", 100);
createTwoWayWeightedEdge(g, "Montreal", "Toronto", 90);
generateFlight("1100", "1200", "AC968", 90);
generateFlight("2000", "2100", "BA360", 90);
createTwoWayWeightedEdge(g, "Edinburgh", "Chicago", 560);
generateFlight("1200", "2000", "BI712", 560);
generateFlight("2100", "0500", "AX023", 560);
createTwoWayWeightedEdge(g, "New Delhi", "Shanghai", 430);
generateFlight("1400", "2000", "AA550", 430);
generateFlight("0600", "1200", "BB102", 430);
createTwoWayWeightedEdge(g, "Shanghai", "Hong Kong", 230);
generateFlight("1400", "1700", "NX450", 230);
generateFlight("2200", "0100", "BL860", 230);
}
return g;
}
private static void createTwoWayWeightedEdge(SimpleDirectedWeightedGraph<String, DefaultWeightedEdge> g, String vertex1, String vertex2, double weight)
{
g.addEdge(vertex1, vertex2);
g.addEdge(vertex2, vertex1);
g.setEdgeWeight(g.getEdge(vertex1, vertex2), weight);
g.setEdgeWeight(g.getEdge(vertex2, vertex1), weight);
String[] tmp1 = {vertex1, vertex2};
myEdges.add(tmp1);
String[] tmp2 = {vertex2, vertex1};
myEdges.add(tmp2);
}
private static void generateFlight(String depTime, String arrTime, String flightNo, double price)
{
Flight f = new Flight(depTime, arrTime, flightNo, price);
flight.add(f);
}
// for displaying flight info nicely
private static String textToPrint(String[] format)
{
String text = " ";
for(int i = 0; i < format.length; i++)
{
switch(i)
{
case 0:
text = text + format[i];
for(int j = format[i].length(); j < 6 ; j++)
text = text + " ";
break;
case 1:
text = text + format[i];
for(int j = format[i].length(); j < 15 ; j++)
text = text + " ";
break;
case 2:
text = text + format[i];
for(int j = format[i].length(); j < 10 ; j++)
text = text + " ";
break;
case 3:
text = text + format[i];
for(int j = format[i].length(); j < 10 ; j++)
text = text + " ";
break;
case 4:
text = text + format[i];
for(int j = format[i].length(); j < 15 ; j++)
text = text + " ";
break;
case 5:
text = text + format[i];
for(int j = format[i].length(); j < 10 ; j++)
text = text + " ";
break;
}
}
return text;
}
#SuppressWarnings({ "rawtypes", "unchecked", "unused" })
private static void calculatePath(SimpleDirectedWeightedGraph<String, DefaultWeightedEdge> g, String startVertex, String endVertex)
{
DijkstraShortestPath path = new DijkstraShortestPath(g, startVertex, endVertex);
path.getPath();
List<Object> edges = path.getPathEdgeList();
String item;
int count = 1;
double totalDuration = 0;
if(edges!=null)
{
System.out.println("\nShortest ( i . e . cheapest ) path :");
String[] labels = {"Leg.", "Leave", "At", "On", "Arrive", "At"};
System.out.println(textToPrint(labels));
for(Object edge : edges)
{
item = edge.toString();
StringTokenizer st = new StringTokenizer(item, ":");
String firstAirport = st.nextToken().trim().substring(1);
String secondAirport = st.nextToken().trim();
secondAirport = secondAirport.substring(0, secondAirport.length()-1);
String depTime = null, arrTime = null, flightNo = null;
double price, flightDuration;
for(int i=0;i<flight.size();i++)
{
if(firstAirport.equals(myEdges.get(i)[0]) && secondAirport.equals(myEdges.get(i)[1]))
{
Flight details = flight.get(i);
flightNo = details.flightNo;
depTime = details.depTime;
arrTime = details.arrTime;
price = details.price;
flightDuration = details.duration;
totalDuration = totalDuration + flightDuration;
String[] tmp = {count+".", firstAirport, depTime, flightNo, secondAirport, arrTime};
System.out.println(textToPrint(tmp));
}
}
count++;
}
System.out.println("Cost of shortest (i.e. cheapest) path = £"+path.getPathLength());
System.out.println("Total time in the air = "+totalDuration+"hrs");
}
else
System.err.println("The path doesn't exist.");
}
}
And Flight.java class:
public class Flight {
String depTime;
String arrTime;
String flightNo;
int duration;
int price;
public Flight(String depTime, String arrTime, String flightNo, double duration){
this.depTime = new String();
this.arrTime = new String();
this.flightNo = new String();
//this.duration = this.getDuration();
}
public int getDuration(){
int duration = Integer.parseInt(arrTime) - Integer.parseInt(depTime);
return duration;
}
public String getFlightNo(){
return flightNo;
}
public double getPrice(){
return price;
}
}
Duration is also not working, but that's not as important. Thanks!!
This looks to be your main problem you aren't storing your arguments in your variables. Rather you are just initializing them. Change your Flight constructor to look like this.
public Flight(String depTime, String arrTime, String flightNo, double duration){
this.depTime = depTime;
this.arrTime = arrTime;
this.flightNo = flightNo;
this.duration = duration;
}
Am getting a java.lang.NullPointerException on an array I have initialized and I can't quite figure it out what am doing wrong. The error is occuring at line 371.
Below is the code of the parent class followed by the class initializng the letterArray ArrayList:
package wordsearch;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Line2D;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
/**
* Main class of Puzzle Program
* #author mungaialex
*
*/
public class WordSearchPuzzle extends JFrame {
private static final long serialVersionUID = 1L;
/** No. Of Columns in Wordlist*/
private static final int WORDLISTCOLS = 1;
static JButton[][] grid; //names the grid of buttons
GridLayout myGridLayout = new GridLayout(1,2,3,3);
/**Array to hold wordList*/
ArrayList<String> wordList;
JButton btnCheck, btnClear;
/** Panel to hold Components to the left*/
JPanel leftSidePanel;
/** Panel to hold components to the right*/
JPanel rightSidePanel;
/**Panel to hold word List*/
JPanel wordListPanel;
/**Panel to hold grid buttons*/
JPanel gridPanel;
/**Panel to hold clear button and check button*/
JPanel buttonsPanel;
/**Panel to hold output textarea*/
JPanel bottomPanel;
private JLabel[] wordListComponents;
#SuppressWarnings("rawtypes")
List puzzleLines;
//Grid Size
private final int ROWS = 20;
private final int COLS = 20;
/** Output Area of system*/
private JTextArea txtOutput;
/**Scrollpane for Output area*/
private JScrollPane scptxtOutput;
private Object[] theWords;
public String wordFromChars = new String();
/** the matrix of the letters */
private char[][] letterArray = null;
/**
* Constructor for WordSearchPuzzle
* #param wordListFile File Containing words to Search for
* #param wordSearhPuzzleFile File Containing the puzzle
*/
public WordSearchPuzzle(String wordSearchFile,String wordsListFile) throws IOException {
FileIO io = new FileIO(wordSearchFile,wordsListFile,grid);
wordList = io.loadWordList();
theWords = wordList.toArray();
addComponentsToPane();
buildWordListPanel();
buildBottomPanel();
io.loadPuzleFromFile();
//Override System.out
PrintStream stream = new PrintStream(System.out) {
#Override
public void print(String s) {
txtOutput.append(s + "\n");
txtOutput.setCaretPosition(txtOutput.getText().length());
}
};
System.setOut(stream);
System.out.print("MESSAGES");
}
/**
* Constructor two
*/
public WordSearchPuzzle() {
}
/**
* Gets the whole word of buttons clicked
* #return
* Returns whole Word
*/
public String getSelectedWord() {
return wordFromChars;
}
/**
* Adds word lists to Panel on the left
*/
private void buildWordListPanel() {
leftSidePanel.setBackground(Color.WHITE);
// Build the word list
wordListComponents = new JLabel[wordList.size()];
wordListPanel = new JPanel(new GridLayout(25, 1));
wordListPanel.setBackground(Color.white);
//Loop through list of words
for (int i = 0; i < this.wordList.size(); i++) {
String word = this.wordList.get(i).toUpperCase();
wordListComponents[i] = new JLabel(word);
wordListComponents[i].setForeground(Color.BLUE);
wordListComponents[i].setHorizontalAlignment(SwingConstants.LEFT);
wordListPanel.add(wordListComponents[i]);
}
leftSidePanel.add(wordListPanel,BorderLayout.WEST);
}
/**
* Adds an output area to the bottom of
*/
private void buildBottomPanel() {
bottomPanel = new JPanel();
bottomPanel.setLayout(new BorderLayout());
txtOutput = new JTextArea();
txtOutput.setEditable(false);
txtOutput.setRows(5);
scptxtOutput = new JScrollPane(txtOutput);
bottomPanel.add(txtOutput,BorderLayout.CENTER);
bottomPanel.add(scptxtOutput,BorderLayout.SOUTH);
rightSidePanel.add(bottomPanel,BorderLayout.CENTER);
}
/**
* Initialize Components
*/
public void addComponentsToPane() {
// buttonsPanel = new JPanel(new BorderLayout(3,5)); //Panel to hold Buttons
buttonsPanel = new JPanel(new GridLayout(3,1));
leftSidePanel = new JPanel(new BorderLayout());
rightSidePanel = new JPanel(new BorderLayout());
btnCheck = new JButton("Check Word");
btnCheck.setActionCommand("Check");
btnCheck.addActionListener(new ButtonClickListener());
btnClear = new JButton("Clear Selection");
btnClear.setActionCommand("Clear");
btnClear.addActionListener(new ButtonClickListener());
buttonsPanel.add(btnClear);//,BorderLayout.PAGE_START);
buttonsPanel.add(btnCheck);//,BorderLayout.PAGE_END);
leftSidePanel.add(buttonsPanel,BorderLayout.SOUTH);
this.getContentPane().add(leftSidePanel,BorderLayout.LINE_START);
gridPanel = new JPanel();
gridPanel.setLayout(myGridLayout);
myGridLayout.setRows(20);
myGridLayout.setColumns(20);
grid = new JButton[ROWS][COLS]; //allocate the size of grid
//theBoard = new char[ROWS][COLS];
for(int Row = 0; Row < grid.length; Row++){
for(int Column = 0; Column < grid[Row].length; Column++){
grid[Row][Column] = new JButton();//Row + 1 +", " + (Column + 1));
grid[Row][Column].setActionCommand(Row + "," + Column);
grid[Row][Column].setActionCommand("gridButton");
grid[Row][Column].addActionListener(new ButtonClickListener());
gridPanel.add(grid[Row][Column]);
}
}
rightSidePanel.add(gridPanel,BorderLayout.NORTH);
this.getContentPane().add(rightSidePanel, BorderLayout.CENTER);
}
public static void main(String[] args) {
try {
if (args.length !=2) { //Make sure we have both the puzzle file and word list file
JOptionPane.showMessageDialog(null, "One or All Files are Missing");
} else { //Files Found
WordSearchPuzzle puzzle = new WordSearchPuzzle(args[0],args[1]);
puzzle.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
puzzle.setSize(new Dimension(1215,740));
//Display the window.
puzzle.setLocationRelativeTo(null); // Center frame on screen
puzzle.setResizable(false); //Set the form as not resizable
puzzle.setVisible(true);
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
public int solvePuzzle( ){
int matches = 0;
for( int r = 0; r < ROWS; r++ )
for( int c = 0; c < COLS; c++ )
for( int rd = -1; rd <= 1; rd++ )
for( int cd = -1; cd <= 1; cd++ )
if( rd != 0 || cd != 0 )
matches += solveDirection( r, c, rd, cd );
return matches;
}
private int solveDirection( int baseRow, int baseCol, int rowDelta, int colDelta ){
String charSequence = "";
int numMatches = 0;
int searchResult;
FileIO io = new FileIO();
charSequence += io.theBoard[ baseRow ][ baseCol ];
for( int i = baseRow + rowDelta, j = baseCol + colDelta;
i >= 0 && j >= 0 && i < ROWS && j < COLS;
i += rowDelta, j += colDelta )
{
charSequence += io.theBoard[ i ][ j ];
searchResult = prefixSearch( theWords, charSequence );
if( searchResult == theWords.length )
break;
if( !((String)theWords[ searchResult ]).startsWith( charSequence ) )
break;
if( theWords[ searchResult ].equals( charSequence ) )
{
numMatches++;
System.out.println( "Found " + charSequence + " at " +
baseRow + " " + baseCol + " to " +
i + " " + j );
}
}
return numMatches;
}
private static int prefixSearch( Object [ ] a, String x ) {
int idx = Arrays.binarySearch( a, x );
if( idx < 0 )
return -idx - 1;
else
return idx;
}
class ButtonClickListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
String command = ((JButton)e.getSource()).getActionCommand();
if (command == "Clear") {
//Enable the buttons that have been disabled and not form a whole word
//JOptionPane.showMessageDialog(null, "Cooming Soon");
for (String word : wordList) {
System.out.print(word);
}
} else if (command == "Check") {
String selectedWord = getSelectedWord();
if (!selectedWord.equals("")){
System.out.print("Selected word is " + getSelectedWord());
//First check if selected word exits in wordList
if (ifExists(selectedWord)) {
if(searchWord(selectedWord)){
JOptionPane.showMessageDialog(null, "Success");
wordFromChars = ""; //Reset the selected Word
}
} else {
JOptionPane.showMessageDialog(null, "[" + selectedWord + "] " +
"Does Not Belong to Word list");
wordFromChars = ""; //Reset the selected Word
}
} else {
JOptionPane.showMessageDialog(null, "No Buttons on Grid have been clicked");
}
} else if (command == "gridButton") {
getSelectedCharacter(e);
((JButton)e.getSource()).setEnabled(false);
}
}
/**
* Gets the character of each button and concatenates each character to form a whole word
* #param e The button that received the Click Event
* #return Whole word
*/
private String getSelectedCharacter (ActionEvent e) {
String character;
character = ((JButton) e.getSource()).getText();
wordFromChars = wordFromChars + character;
return wordFromChars;
}
}
/**
* Checks if selected word is among in wordlist
* #param selectedWord
* #return The word to search for
*/
private boolean ifExists(String selectedWord) {
if (wordList.contains(selectedWord)) {
return true;
}
return false;
}
public boolean searchWord(String word) {
if (!wordList.contains(word)) {
return false;
}
//int index = wordList.indexOf(word);
Line2D.Double line = new Line2D.Double();
//System.out.print("LetterArray is " + letterArray.length);
for (int x = 0; x < letterArray.length; x++) {
for (int y = 0; y < letterArray[x].length; y++) {
// save start point
line.x1 = y; // (y + 1) * SCALE_INDEX_TO_XY;
line.y1 = x; // (x + 1) * SCALE_INDEX_TO_XY;
int pos = 0; // current letter position
if (letterArray[x][y] == word.charAt(pos)) {
// first letter correct -> check next
pos++;
if (pos >= word.length()) {
// word is only one letter long
// double abit = SCALE_INDEX_TO_XY / 3;
line.x2 = y; // (y + 1) * SCALE_INDEX_TO_XY + abit;
line.y2 = x; // (x + 1) * SCALE_INDEX_TO_XY + abit;
return true;
}
// prove surrounding letters:
int[] dirX = { 1, 1, 0, -1, -1, -1, 0, 1 };
int[] dirY = { 0, -1, -1, -1, 0, 1, 1, 1 };
for (int d = 0; d < dirX.length; d++) {
int dx = dirX[d];
int dy = dirY[d];
int cx = x + dx;
int cy = y + dy;
pos = 1; // may be greater if already search in another
// direction from this point
if (insideArray(cx, cy)) {
if (letterArray[cx][cy] == word.charAt(pos)) {
// 2 letters correct
// -> we've got the direction
pos++;
cx += dx;
cy += dy;
while (pos < word.length() && insideArray(cx, cy)
&& letterArray[cx][cy] == word.charAt(pos)) {
pos++;
cx += dx;
cy += dy;
}
if (pos == word.length()) {
// correct end if found
cx -= dx;
cy -= dy;
pos--;
}
if (insideArray(cx, cy) && letterArray[cx][cy] == word.charAt(pos)) {
// we've got the end point
line.x2 = cy; // (cy + 1) *
// SCALE_INDEX_TO_XY;
line.y2 = cx; // (cx + 1) *
// SCALE_INDEX_TO_XY;
/*
* System.out.println(letterArray[x][y] +
* " == " + word.charAt(0) + " (" + line.x1
* + "," + line.y1 + ") ->" + " (" + line.x2
* + "," + line.y2 + "); " + " [" + (line.x1
* / SCALE_INDEX_TO_XY) + "," + (line.y1 /
* SCALE_INDEX_TO_XY) + "] ->" + " [" +
* (line.x2 / SCALE_INDEX_TO_XY) + "." +
* (line.y2 / SCALE_INDEX_TO_XY) + "]; ");
*/
//result[index] = line;
// found
return true;
}
// else: try next occurence
}
}
}
}
}
}
return false;
}
private boolean insideArray(int x, int y) {
boolean insideX = (x >= 0 && x < letterArray.length);
boolean insideY = (y >= 0 && y < letterArray[0].length);
return (insideX && insideY);
}
public void init(char[][] letterArray) {
try {
for (int i = 0; i < letterArray.length; i++) {
for (int j = 0; j < letterArray[i].length; j++) {
char ch = letterArray[i][j];
if (ch >= 'a' && ch <= 'z') {
letterArray[i][j] = Character.toUpperCase(ch);
}
}
}
} catch (Exception e){
System.out.println(e.toString());
}
//System.out.println("It is " + letterArray.length);
this.letterArray = letterArray;
}
}
Here is class initializing the letterArray array:
package wordsearch;
import java.awt.Color;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.SwingConstants;
/**
* Reads wordlist file and puzzle file
* #author mungaialex
*
*/
public class FileIO {
String _puzzleFile, _wordListFile;
/**ArrayList to hold words*/
ArrayList<String> wordList;
/** No. Of Columns in Wordlist*/
private static final int WORDLISTCOLS = 1;
List puzzleLines;
JButton[][] _grid;
char theBoard[][];
private final int _rows = 20;
private final int _columns = 20;
WordSearchPuzzle pz = new WordSearchPuzzle();
/**
* Default Constructor
* #param puzzleFile
* #param wordListFile
*/
public FileIO(String puzzleFile, String wordListFile,JButton grid[][]){
_puzzleFile = new String(puzzleFile);
_wordListFile = new String(wordListFile);
_grid = pz.grid;
}
public FileIO() {
}
/**
* Reads word in the wordlist file and adds them to an array
* #param wordListFilename
* File Containing Words to Search For
* #throws IOException
*/
protected ArrayList<String> loadWordList()throws IOException {
int row = 0;
wordList = new ArrayList<String>();
BufferedReader reader = new BufferedReader(new FileReader(_wordListFile));
String line = reader.readLine();
while (line != null) {
StringTokenizer tokenizer = new StringTokenizer(line, " ");
if (tokenizer.countTokens() != WORDLISTCOLS) {
JOptionPane.showMessageDialog(null, "Error: only one word per line allowed in the word list",
"WordSearch Puzzle: Invalid Format", row);//, JOptionPane.OK_CANCEL_OPTION);
//"Error: only one word per line allowed in the word list");
}
String tok = tokenizer.nextToken();
wordList.add(tok.toUpperCase());
line = reader.readLine();
row++;
}
reader.close();
return wordList;
}
/**
* Reads the puzzle file line by by line
* #param wordSearchFilename
* The file containing the puzzle
* #throws IOException
*/
protected void loadPuzleFromFile() throws IOException {
int row = 0;
BufferedReader reader = new BufferedReader(new FileReader(_puzzleFile));
StringBuffer sb = new StringBuffer();
String line = reader.readLine();
puzzleLines = new ArrayList<String>();
while (line != null) {
StringTokenizer tokenizer = new StringTokenizer(line, " ");
int col = 0;
sb.append(line);
sb.append('\n');
while (tokenizer.hasMoreTokens()) {
String tok = tokenizer.nextToken();
WordSearchPuzzle.grid[row][col].setText(tok);
pz.grid[row][col].setForeground(Color.BLACK);
pz.grid[row][col].setHorizontalAlignment(SwingConstants.CENTER);
puzzleLines.add(tok);
col++;
}
line = reader.readLine();
row++;
theBoard = new char[_rows][_columns];
Iterator itr = puzzleLines.iterator();
for( int r = 0; r < _rows; r++ )
{
String theLine = (String) itr.next( );
theBoard[ r ] = theLine.toUpperCase().toCharArray( );
}
}
String[] search = sb.toString().split("\n");
initLetterArray(search);
reader.close();
}
protected void initLetterArray(String[] letterLines) {
char[][] array = new char[letterLines.length][];
System.out.print("Letter Lines are " +letterLines.length );
for (int i = 0; i < letterLines.length; i++) {
letterLines[i] = letterLines[i].replace(" ", "").toUpperCase();
array[i] = letterLines[i].toCharArray();
}
System.out.print("Array inatoshana ivi " + array.length);
pz.init(array);
}
}
Thanks in advance.
Here it is!
char[][] array = new char[letterLines.length][];
You are only initializing one axis.
When you pass this array to init() and set this.letterArray = letterArray;, the letterArray is also not fully initialized.
Try adding a length to both axes:
char[][] array = new char[letterLines.length][LENGTH];
first you will handle the NullPoinetrException , the code is
if( letterArray != null){
for (int x = 0; x < letterArray.length; x++)
{
..........
............
}
}
I have got a form in Java (Swing) loading large amount of data from the database. I want to display a progress bar while the program gets actually loaded.
How can i do it?
The code is as follows:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.sql.*;
import java.applet.*;
import java.util.*;
import java.awt.Color;
public class bookshow extends JFrame implements MouseListener, ActionListener {
JPanel p1, p2, p3;
JLabel l1, l2, l3, l4;
ImageIcon image;
JButton b[] = new JButton[84];
JButton btnocc, btnbook, btnsel;
ResultSet rs;
private JMenuBar menuBar = new JMenuBar();
private JMenuItem exit, home, save;
private JMenu fileMenu, gotoMenu;
public int cnt = 0, x = 150, y = 90, i, j, put = 0, k = 0, avail = 1, point, x1, y1, count = 0, quan;
public static int prev_click = -1, xpos, ypos;
public static int prev[] = new int[5];
public static int pos[][] = new int[5][2];
public String movname, movdate, movtime;
public bookshow() {
avail = 1;
try {
String sql = "Select * from Pass";
String url = "jdbc:odbc:tbs";
Connection con = DriverManager.getConnection(url);
Statement s = con.createStatement();
rs = s.executeQuery(sql);
while (rs.next()) {
movname = rs.getString("movname");
movdate = rs.getString("movdate");
movtime = rs.getString("movtime");
quan = Integer.parseInt(rs.getString("Quantity"));
}
} catch (Exception ex) {
System.out.println(ex);
}
try {
String sql = "Delete from Pass";
String url = "jdbc:odbc:tbs";
Connection con = DriverManager.getConnection(url);
Statement s = con.createStatement();
s.executeUpdate(sql);
con.close();
} catch (Exception ex) {
System.out.println(ex);
}
setTitle("Select Ticket");
setDefaultCloseOperation(EXIT_ON_CLOSE);
p1 = new JPanel();
getContentPane().add(p1);
p1.setLayout(null);
p1.setBackground(Color.white);
setJMenuBar(menuBar);
fileMenu = new JMenu("File");
menuBar.add(fileMenu);
exit = new JMenuItem("Exit");
exit.addActionListener(this);
fileMenu.add(exit);
exit.setAccelerator(KeyStroke.getKeyStroke('E', Event.CTRL_MASK));
save = new JMenuItem("Save");
save.addActionListener(this);
fileMenu.add(save);
save.setAccelerator(KeyStroke.getKeyStroke('S', Event.CTRL_MASK));
gotoMenu = new JMenu("Go To");
menuBar.add(gotoMenu);
home = new JMenuItem("Home");
//exit.addActionListener(this);
gotoMenu.add(home);
home.setAccelerator(KeyStroke.getKeyStroke('H', Event.CTRL_MASK));
p2 = new JPanel();
p2.setLayout(null);
p2.setBackground(Color.lightGray);
p2.setBounds(100, 50, 500, 20);
p1.add(p2);
l1 = new JLabel("GOLD");
l1.setBounds(240, 0, 100, 20);
p2.add(l1);
l1.setBackground(Color.red);
try {
String sql = "Select * from Book";
String url = "jdbc:odbc:tbs";
Connection con = DriverManager.getConnection(url);
Statement s = con.createStatement();
rs = s.executeQuery(sql);
while (rs.next()) {
String getname = rs.getString("MovName");
String getdate = rs.getString("MovDate");
String gettime = rs.getString("MovTime");
if (movname.equalsIgnoreCase(getname) && movdate.equals(getdate) && movtime.equals(gettime)) {
put = 1;
break;
}
}
} catch (Exception ex) {
System.out.println(ex);
}
for (i = 1; i <= 4; i++) {
for (j = 1; j <= 14; j++) {
point = 0;
b[cnt] = new JButton();
b[cnt].setBounds(x, y, 20, 20);
b[cnt].setBackground(Color.white);
p1.add(b[cnt]);
if (put == 0) {
try {
String sql = "Insert into Book values('" + movname + "','" + movtime + "','" + movdate + "'," + x + "," + y + ",1)";
String url = "jdbc:odbc:tbs";
Connection con = DriverManager.getConnection(url);
Statement s = con.createStatement();
s.executeUpdate(sql);
con.close();
} catch (Exception ex) {
System.out.println(ex);
}
} else {
try {
String sql = "Select * from Book";
String url = "jdbc:odbc:tbs";
Connection con = DriverManager.getConnection(url);
Statement s = con.createStatement();
rs = s.executeQuery(sql);
while (rs.next()) {
String getname = rs.getString("MovName");
String getdate = rs.getString("MovDate");
String gettime = rs.getString("MovTime");
avail = Integer.parseInt(rs.getString("Avail"));
if (movname.equalsIgnoreCase(getname) && movdate.equals(getdate) && movtime.equals(gettime)) {
k++;
if (avail == 0 && k == (cnt + 1)) {
b[cnt].setBackground(Color.red);
point = 1;
b[cnt].setEnabled(false);
}
}
}
} catch (Exception ex) {
System.out.println(ex);
}
}
if (point == 0) {
b[cnt].addMouseListener(this);
}
cnt++;
x = x + 30;
k = 0;
}
x = 150;
y = y + 40;
}
y = 300;
x = 150;
p3 = new JPanel();
p3.setLayout(null);
p3.setBackground(Color.lightGray);
p3.setBounds(100, 260, 500, 20);
p1.add(p3);
l2 = new JLabel("ECONOMY");
l2.setBounds(220, 0, 100, 20);
p3.add(l2);
l2.setBackground(Color.red);
for (i = 1; i <= 2; i++) {
for (j = 1; j <= 14; j++) {
point = 0;
b[cnt] = new JButton();
b[cnt].setBounds(x, y, 20, 20);
b[cnt].setBackground(Color.white);
p1.add(b[cnt]);
if (put == 0) {
try {
String sql = "Insert into Book values('" + movname + "','" + movtime + "','" + movdate + "'," + x + "," + y + ",1)";
String url = "jdbc:odbc:tbs";
Connection con = DriverManager.getConnection(url);
Statement s = con.createStatement();
s.executeUpdate(sql);
con.close();
} catch (Exception ex) {
System.out.println(ex);
}
} else {
try {
String sql = "Select * from Book";
String url = "jdbc:odbc:tbs";
Connection con = DriverManager.getConnection(url);
Statement s = con.createStatement();
rs = s.executeQuery(sql);
while (rs.next()) {
String getname = rs.getString("MovName");
String getdate = rs.getString("MovDate");
String gettime = rs.getString("MovTime");
avail = Integer.parseInt(rs.getString("Avail"));
if (movname.equalsIgnoreCase(getname) && movdate.equals(getdate) && movtime.equals(gettime)) {
k++;
if (avail == 0 && k == (cnt + 1)) {
b[cnt].setBackground(Color.red);
point = 1;
b[cnt].setEnabled(false);
}
}
}
} catch (Exception ex) {
System.out.println(ex);
}
}
if (point == 0) {
b[cnt].addMouseListener(this);
}
cnt++;
x = x + 30;
k = 0;
}
x = 150;
y = y + 40;
}
image = new ImageIcon("screen.jpg");
l3 = new JLabel(image);
l3.setBounds(70, y + 20, 600, 54);
p1.add(l3);
l4 = new JLabel("Seat to Occupy");
l4.setBounds(140, 490, 100, 15);
p1.add(l4);
btnocc = new JButton();
btnocc.setBounds(260, 490, 15, 15);
btnocc.setBackground(Color.white);
p1.add(btnocc);
l4 = new JLabel("Booked seat");
l4.setBounds(320, 490, 80, 15);
p1.add(l4);
btnbook = new JButton();
btnbook.setBounds(410, 490, 15, 15);
btnbook.setBackground(Color.red);
p1.add(btnbook);
l4 = new JLabel("Current selection");
l4.setBounds(460, 490, 100, 15);
p1.add(l4);
btnsel = new JButton();
btnsel.setBounds(570, 490, 15, 15);
btnsel.setBackground(Color.green);
p1.add(btnsel);
setSize(770, 650);
setVisible(true);
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
Cursor mycursor = new Cursor(Cursor.HAND_CURSOR);
setCursor(mycursor);
}
public void mouseExited(MouseEvent e) {
Cursor mycursor = new Cursor(Cursor.DEFAULT_CURSOR);
setCursor(mycursor);
}
public void mouseClicked(MouseEvent e) {
int row, col, ex;
for (i = 0; i < cnt; i++) {
if (e.getSource().equals(b[i])) {
if (count < quan) {
prev[count] = i;
b[prev[count]].setBackground(Color.green);
row = i / 14;
col = i % 14;
x1 = 150 + (30 * col);
if (row >= 0 && row <= 3) {
y1 = 90 + (40 * row);
} else {
y1 = 300 + (40 * (row - 4));
}
pos[count][0] = x1;
pos[count][1] = y1;
count++;
} else {
ex = prev[0];
b[ex].setBackground(Color.white);
for (int j = 0; j <= (count - 1); j++) {
prev[j] = prev[j + 1];
pos[j][0] = pos[j + 1][0];
pos[j][1] = pos[j + 1][1];
}
prev[count - 1] = i;
row = i / 14;
col = i % 14;
x1 = 150 + (30 * col);
if (row >= 0 && row <= 3) {
y1 = 90 + (40 * row);
} else {
y1 = 300 + (40 * (row - 4));
}
pos[count - 1][0] = x1;
pos[count - 1][1] = y1;
for (int j = 0; j <= (count - 1); j++) {
b[prev[j]].setBackground(Color.green);
}
count = quan;
}
}
}
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == save) {
if (count != quan) {
JOptionPane.showMessageDialog(null, "Please select the exact numbers of seat", "Error", JOptionPane.ERROR_MESSAGE);
} else {
for (i = 0; i < count; i++) {
try {
String sql = "Update Book set Avail=0 where MovName='" + movname + "' AND MovDate='" + movdate + "' AND MovTime='" + movtime + "' AND X=" + pos[i][0] + " AND y=" + pos[i][1] + " ";
String url = "jdbc:odbc:tbs";
Connection con = DriverManager.getConnection(url);
Statement s = con.createStatement();
s.executeUpdate(sql);
con.close();
} catch (Exception ex) {
System.out.println(ex);
}
setVisible(false);
bookmain bm = new bookmain();
}
}
}
}
public static void main(String args[]) {
bookshow mm = new bookshow();
}
}
Java progress bar tutorial should help.
Another example can be found in SwingWorker java docs entry.
Instead of calling the nextPrimeNumber() it could be in your case processNextBook().
To work out the progress you could use a similar idea as bellow changing to the variables to something meaningful in your code eg. setProgress(100 * booksProcessed.size() / books.size());
The code bellow should give you the basic idea how to achieve what your looking for.
class PrimeNumbersTask extends
SwingWorker<List<Integer>, Integer> {
PrimeNumbersTask(JTextArea textArea, int numbersToFind) {
//initialize
}
#Override
public List<Integer> doInBackground() {
while (! enough && ! isCancelled()) {
number = nextPrimeNumber();
publish(number);
setProgress(100 * numbers.size() / numbersToFind);
}
}
return numbers;
}
#Override
protected void process(List<Integer> chunks) {
for (int number : chunks) {
textArea.append(number + "\n");
}
}
}
JTextArea textArea = new JTextArea();
final JProgressBar progressBar = new JProgressBar(0, 100);
PrimeNumbersTask task = new PrimeNumbersTask(textArea, N);
task.addPropertyChangeListener(
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
progressBar.setValue((Integer)evt.getNewValue());
}
}
});
JProgressBar is your choice
Here is a short, self-contained example of using SwingWorker to query a database and update a JProgressBar.