I have the following class:
public class PDFValues {
private String value;
private int xPos;
private int yPos;
public PDFValues(){
}
public PDFValues(String value, int x, int y){
this.setValue(value);
this.setX(x);
this.setY(y);
}
public void setValue(String value){
this.value = value;
}
public void setX(int x){
this.xPos = x;
}
public void setY(int y){
this.yPos = y;
}
public String getValue(){
return this.value;
}
public int getX(){
return this.xPos;
}
public int getY(){
return this.yPos;
}
}
And then I want to do this:
public class PDFtoJSONTest {
public static void main(String[] args) {
List<PDFValues> listaElementos = new ArrayList<PDFValues>();
listaElementos.add(new PDFValues("Anubis Lockward Botello",
new Integer(100), new Integer(633)));
....more code
}
}
What I want to do, is save all the PDFValues in the ArrayList, as a JSON file, but I don't know how to make it automatic, I thought of Serializing the object or something, but I can't find a solution to this and I'm not sure how I could make the PDFValues object serializable.
I want to do this to save those values in a JSON file and then use them as properties to generate a PDF file, I'm using PDFBox for the generation of the PDFs files and SimpleJSON for the .json ones.
I'm working on a project where I'd have to generate thousands of pdf files out of some processed data. I've already managed to parse the data which consists of about 500+ MBs of text and holds around five thousand account statements which need to be generated as PDFs.
The thing is, that seeings as the Text data is generated in PDFs, one needs to indicate the position of the starting character in a string to PDFValues, to generate a PDFTextInfo object and then add it to the PDF, the file would need to contain images and text and other stuff.
Note: If there's a better way to accomplish what I'm trying to do, I'm open to suggestions, but I'd also like an answer to what I'm trying to do, and know if it would work or not, and why for both cases.
I'd like to make my code as fast as possible, right now I'm able to process the whole TXT file from RAW to mostly clean data in under 2 minutes and I know it might be optimized but right now that's not the point :D
I'd like to generate the PDFs files as fast as possible, but I've been working with that project in Java for like 1 1/2 months now, and I've only learned about JSON and PDF file generation in the past week...it's been three days of working on the JSON file and I'm a bit lost.
Here's an example of the file output for the JSON file that I'm trying to accomplish, this one I generated it manually and I managed to read and process the file, now I'm trying to generate it automatically:
{
"Header": {
"FullName":
{
"Name":"Anubis Lockward Botello",
"Horizontal":180,
"Vertical":633
},
..... more elements .....
}
}
As you can see, I'm trying to divide the elements on the pdf files as if they were panels, like HEADER, BALANCES, TRANSACTIONS and stuff, and build the PDF file as if they were pieces of a puzzle, but right now I'm trying to "build" the name element on the header.
I would guess there is a better way to do build PDF files than writing and then re-reading a file, but I can provide one answer for your JSON question.
Use the Apache commons-lang3 library and look into ToStringBuilder. You can then define a toString() method on your object and use the built-in ToStringStyle.JSON_STYLE format. You'd then have to wrap your list of PDFValues in some other object that can store a PDFValue for Header, FullName, etc..
#Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.JSON_STYLE)
.append("Name", value)
.append("Horizontal", xPos)
.append("Vertical", yPos)
.toString();
}
I should note that you could pull in Jackson or similar libraries, annotate your objects with the required JsonProperty annotations and use the library to serialize your object to JSON as you would for REST or similar. But, for a simple use case like yours, the ToStringBuilder is simple and effective.
OK, I managed to get this far thanks to JudgingNotJudging, what I did was taking his answer and applying a Decorator Pattern to the object, so that I have a PDFValue, that's inside a PDFElement, that's part of a PDFContainer, so it goes like this:
Header: (this is our PDFContainer)
FullName: (so, Header HAS-A FullName element)
PDFValue: (and FullName HAS-A a PDFValue, that has the Name or value to be shown, and the X and Y coordinates inside the PDF)
Here's the code:
The PDFValue class is still the same, and I added the overridden toString() method according to JudgingNotJudging's answer.
public class PDFValuesDecorator extends PDFValues{
}
In PDFValuesDecorator we don't do anything, we're just going to extend PDFValues so that we have the correct type of the class we want to add behavior to, and still get a common type for all the different classes we might create this way.
public class PDFElement extends PDFValuesDecorator {
private PDFValues pdfValue;
private String elementID;
public PDFElement(PDFValues pdfValue, String elementID){
this.pdfValue = pdfValue;
this.elementID = elementID;
}
#Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.JSON_STYLE)
.append(elementID, pdfValue.toString())
.toString();
}
}
In the constructor we save the instance of the object we're trying to "wrap" so that we can "add" something to it. In this case, we're adding an ID for the element and we're modifying the toString() method of the element to also include the toString() method of the PDFValue, so that they both show both of their values in the appropriate order.
Finally, here's my main method:
public class PDFtoJSONTest {
public static void main(String[] args) {
List<PDFValues> listaElementos = new ArrayList<PDFValues>();
PDFValues name =
new PDFValues(
"Anubis Lockward Botello",
new Integer(100),
new Integer(633)
);
PDFElement fullName = new PDFElement(name, "FullName");
PDFElement header = new PDFElement(fullName, "Header");
listaElementos.add(header);
for(PDFValues value : listaElementos){
System.out.println("Valor: " + value.toJSONString());
}
}
}
As you can see, the first thing I do is create an ArrayList of PDFValues, then I create a single object for the name value, then that name is wrapped inside the FullName element, and then that's stored inside a Header element. As you can see, I can pass around the List object and do with it whatever I want.
And also, I could create other PDFElements like images and stuff, and I can save all of them inside the ArrayList and pass them around and then when I want to save them, I just have to call the toString method once and I would get the correct output, btw, here's the resulting value from the JSON string:
Valor: {"Header":"{"FullName":"{"Name":"Anubis Lockward Botello","Horizontal":100,"Vertical":633}"}"}
Related
I have been trying to figure this for 1hr30 now and its too confusing for what seems like a really simple problem so I came here to ask.
I send a get request to a 3rd party API to get anime (movie) details as xml.
I store these in a class Ann.java that was automatically generated by netbean's JAXB xml bindings from a sample xml response.
Originally the xml file I used returned only a single anime entry so I could use
String output = gt.fetchMovie().getAnime().getName();
Where gt is my web service. This would print the name of the anime to my IDE.
I changed the setup so that the 3rd party API response gives me multiple anime results instead of just one. I now search for "evangelion" and get 3 results.
However, the new schema of the xml and java class means that attributes are stored as lists. E.g. if I want to access an anime's getName it is within this structure:
public class Ann {
protected List<Object> animeOrManga;
public List<Object> getAnimeOrManga() {
if (animeOrManga == null) {
animeOrManga = new ArrayList<Object>();
}
return this.animeOrManga;
}
public String getName() {
return name;
}
I have been trying to figure out how to return getName but can't find anything that explains what I want to do. I'm not smart enough to just "figure this out" and have been 1hr30 trial and error already.
I know I want to do something like this but guessing the syntax is impossible and everything just goes red, or cannot find symbol, or whatever.
List<Object> = gt.fetchMovie().getAnimeOrManga();
For each (list object)
getName();
Thankyou for reading!
how about create a class that has name attribute like
public class Animal {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
then you can use with
List<Animal> animeOrManga = gt.fetchMovie().getAnimeOrManga();
then you can use with each.
The pseudocodish you provided can be written in Java as follows:
List<Ann> list = new ArrayList<Ann> // You want the list as specific as possible
list.clone(gt.getAnimeOrManga());
for(Ann listObject : list) { // For each loop
listObject.getName();
}
What is used is a for-each loop, which is exactly what is sounds: for each thing in this list do this.
The clone() method takes an arraylist and copies it into the new one.
See here: How do I copy the contents of one ArrayList into another?
I'm trying to make an array of objects called Verbs.
The Verb class has 4 Strings.
public class Verb {
String maori;
String englishPast;
String englishPresent;
String englishFuture;
}
Do I need to write get and set methods into this class in order to change these values or does android handle it for you somehow?
This seems to not be an Android problem but a java related question. You should create a Verb class like this:
public class Verb {
private String maori;
//All other strings you need
public String getMaori() {
return maori;
}
//Add a setter as well
Then you should create your Verb objects and add these objects to your array. But this has nothing to do with Android at all!
Ok so I've been reading up on good practices for using constants and enums but I still am confused as to what should I do.
Basically I need to store strings with paths to assets like
"/assets/sprites/ball.png"
and then i need simple name strings like "ball" and I want them to be related to each other.
Those strings will be used very often and in different files/packages all across my game's code.
I have a TextureAtlas class that given the name ("ball") already provides me with the actual resource (graphics ready to draw etc). But when I need to load the resource i need to give actual path, not just name. I want to have 1 place where I will have all the constants declared and it would be nice if both the "name" constant and "path" constant were related somehow. So that I don't have to put actual path to the file whenever I want something to use that graphic, instead I want to use constant with the name String.
I hope you can understand what I mean.
Well, I think I could use a map, where key would be the name ("ball") and value would be path ("/assets/ball.png") but I still want to be able to just lets say, write something like this
Assets.GetSprite(Assets.BALL);
and get an actual resource, or even better
Assets.GetSprite(BALL);
So there is this problem of constants, that I need to define name and corresponding path for my graphics in 1 place and be able to use it from anywhere in the program if I need it.
It all needs to be in one place so that whenever I add new resource, like new sound or new sprite to the game I won't have to look all over my program to find the place where it should be manually typed, I want to have that 1 file that I will go over and just add new constant or something like that for that 1 file.
Cheers,
Pablo.
It might be a good idea to use properties file.
Java Properties
config.properties
ball = /assets/sprites/ball.png
user = /assets/sprites/user.png
To read these values, at the game startup, do following
FileHandle propertiesFileHandle = Gdx.files
.internal(PROPERTIES_FILE_PATH);
PROPERTIES = new Properties();
try {
PROPERTIES.load(new BufferedInputStream(propertiesFileHandle.read()));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Now you can share this PROPERTIES object wherever you need.
String ballPath = PROPERTIES.getProperty("ball");
Hope this helps.
What is the problem with the Map? Create a static HashMap and store you mapping there. You can directly get your values from there.
OR
if you simply need mappings where you key and values are constants then you can put them in an interface (Variables are by default public static and final).
I would go for something like this:
public enum Assets {
BALL, PLAYER // and so on
}
public class Configuration {
Map<Assets, String> values= new HashMap<Assets, String>();
public String getPathFor(Assets asset){
if(!values.containsKey(asset)) throw new IllegalArgumentException();
return values.get(asset);
}
/* Contains further logic to persist configuration */
}
So you have well defined Assets and a Configuration object, where you store further Information.
You can create more complicated enums with parameters. Take a look at the Planet enum in this example http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html or here is an example specific to your project. Remember that are required to create the constructor and the constructor must be private.
public class Asset {
public enum AssetType {
BALL("/assets/sprites/ball.png"),
USER("/assets/sprites/user.png");
private final String path;
AssetsType(String path) {
this.path = path;
}
public String getPath() {
return this.path;
}
}
private AssetType assetType;
public Asset(AssetType assetType) {
this.assetType = assetType;
}
// ...
}
I have been looking for this answer for the past 2 hours with no luck so I am posting my question now. I am sorry if it is similar to one already asked but I could not get an clear answer from what was already answered.
Here goes:
I am doing a school project in which we read in a text file of "Computer" objects (there are 8 fields in total in this form: manufacturer:model:memory:diskMemory:CPU:opticalDrive:OSVersion:RetailPrice)
once the file is read you are supposed to separate the fields and construct an array of Computer objects using the constructor that accepts all the above parameters (separated) and store their reference in each position of the array.
Here is where my question is:
Afterwards you display a menu and the user selects a few option, the simplest is just to display the list of computer object in the following form on a JOPtionPane:
Manufacturer1 model1 memory1 disk1 CPU1 optical1 OS1 retailPrice1
Manufacturer2 model2 memory2 disk2 CPU2 optical2 OS2 retailPrice2
and so on until you finish the array. I cannot figure out how to condense the array of objects into a single string that is in the form above. The Computer class has a getMethod for each of those fields I am just having trouble getting them to be aligned in that way. It has to be on a JOPtionPane the simple .INFORMATION_MESSAGE kind. If you all need to see the Computer class code let me know and I can post it. This is my first time posting on this website so I apologize if it is in improper form.
Thank you so much for your help,
Bob
EDIT:
This is what the output should look like:
http://i229.photobucket.com/albums/ee38/Yukijin-Uchiha/ScreenShot2014-03-14at113759AM_zps05b5dbb5.png
If you implement the Computer classes toString() function properly, you should get just what you want. For example:
public class Computer {
public String toString() {
return (new StringBuilder(getManufacturer()).append(":").
append(getModel()).append(":").
append(getMemory()).append(":").
append(getDiskMemory()).append(":").
append(getCPU()).append(":").
append(getOpticalDrive()).append(":").
append(getOSVersion()).append(":").
append(getRetailPrice()).
toString();
}
}
Then call it with
String computerObjAsString = aComputerInstance.toString();
To do this with an array of Computer objects:
StringBuilder outBldr = new StringBuilder();
for(Computer cmptr : anArrayOfComputers) {
outBldr.append(cmptr).append(System.getPropetry("line.separator", "\r\n"));
}
System.out.println(outBldr);
You should look to override the toString() method in your Computer objects to include the details that you want printed. Then, for each Computer object in your array, call <object name>.toString() to display the appropriate information.
public class Computer {
private String name;
private String type;
public Computer(String n, String t) {
this.name = n;
this.type = t;
}
public String toString() {
return "Name: " + this.name + " Type: " + this.type;
}
public static void main(String[] args) {
Computer c = new Computer("atari","old-school");
System.out.println(c.toString());
}
}
An example is as follows:
SEG1|asdasd|20111212|asdsad
SEG2|asdasd|asdasd
SEG3|sdfsdf|sdfsdf|sdfsdf|sdfsfsdf
SEG4|sdfsfs|
Basically, each SEG* line needs to be parsed into a corresponding object, defining what each of those fields are. Some, such as the third field in SEG1 will be parsed as a Date.
Each object will generally stay the same but there may be instances in which an additional field may be added, like so:
SEG1|asdasd|20111212|asdsad|12334455
At the moment, I'm thinking of using the following type of algorithm:
List<String> segments = Arrays.asList(string.split("\r"); // Will always be a CR.
List<String> fields;
String fieldName;
for (String segment : segments) {
fields = Arrays.asList(segment.split("\\|");
fieldName = fields.get(0);
SEG1 seg1;
if (fieldName.compareTo("SEG1") == 0) {
seg1 = new Seg1();
seg1.setField1(fields.get(1));
seg1.setField2(fields.get(2));
seg1.setField3(fields.get(3));
} else if (fieldName.compareTo("SEG2") == 0) {
...
} else if (fieldName.compareTo("SEG3") == 0) {
...
} else {
// Erroneous/failure case.
}
}
Some fields may be optional as well, depending on the object being populated. My concern is if I add a new field to a class, any checks that use the expect field count number will also need to be updated. How could I go about parsing the rows, while allowing for new or modified field types in the class objects to populate?
If you can define a common interface for all to be parsed classes I would suggest the following:
interface Segment {}
class SEG1 implements Segment
{
void setField1(final String field){};
void setField2(final String field){};
void setField3(final String field){};
}
enum Parser {
SEGMENT1("SEG1") {
#Override
protected Segment parse(final String[] fields)
{
final SEG1 segment = new SEG1();
segment.setField1(fields[0]);
segment.setField1(fields[1]);
segment.setField1(fields[2]);
return segment;
}
},
...
;
private final String name;
private Parser(final String name)
{
this.name = name;
}
protected abstract Segment parse(String[] fields);
public static Segment parse(final String segment)
{
final int firstSeparator = segment.indexOf('|');
final String name = segment.substring(0, firstSeparator);
final String[] fields = segment.substring(firstSeparator + 1).split("\\|");
for (final Parser parser : values())
if (parser.name.equals(name))
return parser.parse(fields);
return null;
}
}
For each type of segment add an element to the enum and handle the different kinds of fields in the parse(String[])method.
You can use collections, e.g. ArrayList
You can use var-args
If you want to make it extensible, you may want to process each segment in a loop, instead of handling each occurance.
I would add a header row to your file format with the names of the fields being stored in the file so it looks something more like this:
(1) field1|field2|field3|field4|field5
(2) SEG1|asdasd|20111212|asdsad|
(3) SEG2|asdasd||asdasd|
(4) SEG3|sdfsdf|sdfsdf|sdfsdf|sdfsfsdf
(5) SEG4|sdfsfs|||
This is common for CSV files. I've also added more delimiters so that each line has five 'values'. This way a null value can be specified by just entering two delimiters in a row (see the third row above for an example where a null value is not the last value).
Now your parsing code knows what fields need to be set and you can call the setters using reflection in a loop. Pseudo code:
get the field names from the first line in the file
for (every line in the file except the first one) {
for (every value in the line) {
if (the value is not empty) {
use reflection to get the setter for the field and invoke it with the
value
}
}
}
This allows you to extend the file with additional fields without having to change the code. It also means you can have meaningful field names. The reflection may get a bit complicated with different types e.g. int, String, boolean etc. so I would have to say that if you can, follow #sethu's advice and use a ready-built proven library that does this for you.
Is there a necessity to use the same string with | as a delimiter? If the same classes are used to create the String, then its an ideal case for Xstream. Xstream will convert your java object into XML and back. Xstream will take care of the scenario where some fields are optional. You will not have write any code that parses your text. Here's a link:
http://x-stream.github.io/