Loading Images from a Jarfile - java

Alright so here is my problem and my question to you.....
I have a game in which it needs to load images from the jar file (all the images are packed into the jar file like so):
I first have the unzip of the jar file:
Then it goes to:
Then inside each of those folder i have something that looks like this:
Now reminder above is the Jarfile GameClient.jar unziped and you see where the cards are in it.
So here is my code for trying to load each and every one of those images into memory
private void addCardsAndChangeSize() throws IOException
{
String tempString;
ImageIcon tempIcon;
allCards.clear();
ClassLoader cldr = this.getClass().getClassLoader();
URL imageURL;
for(int i = 0; i < all.length; i++)
{
for(int x = 0; x < clubs.length; x++)
{
tempString = all[i][x];
tempString = "/cards/"+cardFolders[i]+"/"+tempString;
imageURL = cldr.getResource(tempString);
tempIcon = resizeImage(new ImageIcon(imageURL),70,70,false);
tempString = all[i][x];
tempIcon.setDescription(tempString);
allCards.add(tempIcon);
}
}
backCard = resizeImage(new ImageIcon(cldr.getResource(back)),70,70,false);
}
So i call that in the contructor to load all the images into an ArrayList here is the whole class if you want to know what i do.
package global;
import java.awt.*;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Cards
{
private ImageIcon backCard = new ImageIcon("cards/backCard.jpg");
private String back = "/cards/backCard.jpg";
private String[] cardFolders = {
"clubs","diamonds","hearts","spades"
};
private String[] clubs = {
"aceClubs.jpg","eightClubs.jpg","fiveClubs.jpg","fourClubs.jpg","jackClubs.jpg",
"kingClubs.jpg","nineClubs.jpg","queenClubs.jpg","sevenClubs.jpg","sixClubs.jpg",
"tenClubs.jpg","threeClubs.jpg","twoClubs.jpg"
};
private String[] diamonds = {
"aceDia.jpg","eightDia.jpg","fiveDia.jpg","fourDia.jpg","jackDia.jpg","kingDia.jpg",
"nineDia.jpg","queenDia.jpg","sevenDia.jpg","sixDia.jpg","tenDia.jpg","threeDia.jpg",
"twoDia.jpg"
};
private String[] hearts = {
"aceHearts.jpg","eightHearts.jpg","fiveHearts.jpg","fourHearts.jpg","jackHearts.jpg",
"kingHearts.jpg","nineHearts.jpg","queenHearts.jpg","sevenHearts.jpg","sixHearts.jpg",
"tenHearts.jpg","threeHearts.jpg","twoHearts.jpg"
};
private String[] spades = {
"aceSpades.jpg","eightSpades.jpg","fiveSpades.jpg","fourSpades.jpg","jackSpades.jpg",
"kingSpades.jpg","nineSpades.jpg","queenSpades.jpg","sevenSpades.jpg","sixSpades.jpg",
"tenSpades.jpg","threeSpades.jpg","twoSpades.jpg"
};
private String[][] all = {
clubs,diamonds,hearts,spades
};
private ArrayList<ImageIcon> allCards = new ArrayList<ImageIcon>();
public Cards()
{
try
{
addCardsAndChangeSize();
shuffle();
}
catch(Exception e)
{e.printStackTrace();}
}
/**
* #param x Cards name with extension
* #return Face Value of Card
*/
public static int getFaceValue(String x)
{
int face = 0;
switch(x)
{
case "aceClubs.jpg":
case "aceDia.jpg":
case "aceHearts.jpg":
case "aceSpades.jpg":
face = 1;
break;
case "eightClubs.jpg":
case "eightDia.jpg":
case "eightHearts.jpg":
case "eightSpades.jpg":
face = 8;
break;
case "fiveClubs.jpg":
case "fiveDia.jpg":
case "fiveHearts.jpg":
case "fiveSpades.jpg":
face = 5;
break;
case "fourClubs.jpg":
case "fourDia.jpg":
case "fourHearts.jpg":
case "fourSpades.jpg":
face = 4;
break;
case "jackClubs.jpg":
case "jackDia.jpg":
case "jackHearts.jpg":
case "jackSpades.jpg":
case "kingClubs.jpg":
case "kingDia.jpg":
case "kingHearts.jpg":
case "kingSpades.jpg":
case "queenClubs.jpg":
case "queenDia.jpg":
case "queenHearts.jpg":
case "queenSpades.jpg":
case "tenClubs.jpg":
case "tenDia.jpg":
case "tenHearts.jpg":
case "tenSpades.jpg":
face = 10;
break;
case "twoClubs.jpg":
case "twoDia.jpg":
case "twoHearts.jpg":
case "twoSpades.jpg":
face = 2;
break;
case "threeClubs.jpg":
case "threeDia.jpg":
case "threeHearts.jpg":
case "threeSpades.jpg":
face = 3;
break;
case "sixClubs.jpg":
case "sixDia.jpg":
case "sixHearts.jpg":
case "sixSpades.jpg":
face = 6;
break;
case "sevenClubs.jpg":
case "sevenDia.jpg":
case "sevenHearts.jpg":
case "sevenSpades.jpg":
face = 7;
break;
case "nineClubs.jpg":
case "nineDia.jpg":
case "nineHearts.jpg":
case "nineSpades.jpg":
face = 9;
break;
}
return face;
}
//shuffles all the cards in the deck
private void shuffle()
{
long seed = System.nanoTime();
Collections.shuffle(allCards, new Random(seed));
}
/**
* Chooses a card at random from the deck. Also removes that card when chosen
* #return randomly chosen card
*/
public ImageIcon getRandomCard()
{
int index = ((int)Math.random() * allCards.size());
return allCards.remove(index);
}
/**
* #return Image of the back of a card
*/
public ImageIcon getBackCard()
{return backCard;}
public static ImageIcon parseImage(String x)
{
if(x.contains("Dia"))
return new ImageIcon("cards/diamonds/"+x);
else
if(x.contains("Clubs"))
return new ImageIcon("cards/clubs/"+x);
else
if(x.contains("Hearts"))
return new ImageIcon("cards/hearts/"+x);
else
if(x.contains("Spades"))
return new ImageIcon("cards/spades/"+x);
return null;
}
//adds all the cards and adds a description to them loaded into memory
private void addCardsAndChangeSize() throws IOException
{
String tempString;
ImageIcon tempIcon;
allCards.clear();
ClassLoader cldr = this.getClass().getClassLoader();
URL imageURL;
for(int i = 0; i < all.length; i++)
{
for(int x = 0; x < clubs.length; x++)
{
tempString = all[i][x];
tempString = "/cards/"+cardFolders[i]+"/"+tempString;
imageURL = cldr.getResource(tempString);
tempIcon = resizeImage(new ImageIcon(imageURL),70,70,false);
tempString = all[i][x];
tempIcon.setDescription(tempString);
allCards.add(tempIcon);
}
}
backCard = resizeImage(new ImageIcon(cldr.getResource(back)),70,70,false);
}
//resizes images
public ImageIcon resizeImage(ImageIcon imageIcon, int width, int height, boolean max)
{
Image image = imageIcon.getImage();
Image newimg = image.getScaledInstance(-1, height, java.awt.Image.SCALE_SMOOTH);
int width1 = newimg.getWidth(null);
if ((max && width1 > width) || (!max && width1 < width))
newimg = image.getScaledInstance(width, -1, java.awt.Image.SCALE_SMOOTH);
return new ImageIcon(newimg);
}
}
I keep getting null pointer exception on the tempIcon = resizeImage(new ImageIcon(imageURL),70,70,false);
Can anyone tell me why this isn't loading the images properly? Reminder i am pre-loading them into memory. My question is not how to make this better i am just simply asking what am i doing wrong with the class loader and stuff like that......
I am somewhat new at java and i know some of this code will look horrible to you but please again i am not asking how to make this code "pro" im just looking for the explanation why its giving me null.
Thanks!
P.S. If you need more pictures of info or w.e. i will try to put that up right away

Your problem is that cldr.getResource(tempString); does not return object but null. Then, something is wrong with tempString. Classloader cannot find this file, so returns null.
Change tempString = "/cards/"+cardFolders[i]+"/"+tempString;
To tempString = "cards/"+cardFolders[i]+"/"+tempString;

You should be using the getResource of Class, not ClassLoader. The getResource method in Class does useful transformations on the path before giving it to the ClassLoader version of the method, like deciding if the path is relative to the class or absolute, and so ClassLoader doesn't expect to see things like / at the start of the path. You can see this clearly in the getResource javadoc.

So i found out the solution i still don't quite understand why this is the answer but here ya go.
This is the revised code and works fine
private void addCardsAndChangeSize() throws Exception
{
String tempString;
ImageIcon tempIcon;
allCards.clear();
URL imageURL;
for(int i = 0; i < all.length; i++)
{
for(int x = 0; x < clubs.length; x++)
{
tempString = all[i][x];
tempString = "/cards/"+cardFolders[i]+"/"+tempString;
imageURL = this.getClass().getResource(tempString);
System.out.println(tempString);
System.out.println(imageURL == null);
tempIcon = resizeImage(new ImageIcon(imageURL),70,70,false);
tempString = all[i][x];
tempIcon.setDescription(tempString);
allCards.add(tempIcon);
}
}
backCard = resizeImage(new ImageIcon(this.getClass().getResource(back)),70,70,false);
}
You have to have that "/cards/" and also you this.getClass().getResource(String res);
Thanks for all your help guys!

Related

Attempting to instantiate in loop, get unexpected type (expected variable)

I'm trying to instantiate three objects in a loop so that I don't reuse the constructor text. This is because, for Uni, we get marked down if we reuse the same line of code (it's marked automatically).
My code is as follows:
EnemyShip enemy1;
EnemyShip enemy2;
EnemyShip enemy3;
public Game()
{
for (int i = 1; i <= 3; i++) {
getEnemyRef(i) = new EnemyShip(); //getEnemyRef unexpected type - required:variable found:value
//enemy1 = new EnemyShip(); works normally
}
}
The i is underlined and I am told that it is a value not variable.
Please note that I use the following code instead of a list or array because we are not allowed to use them for this task.
public EnemyShip getEnemyRef(int enemy) {
switch (enemy)
{
case 1:
return enemy1;
case 2:
return enemy2;
case 3:
return enemy3;
}
return null;
}
The marking system bases how many times a line is reused from how many times it is written in source code, not how many times it is executed
This snippet should do the trick:
public void setEnemyRef(int enemyFlag, EnemyShip enemy){
switch (enemyFlag){
case 1:
enemy1 = enemy;
break;
case 2:
enemy2 = enemy;
break;
case 3:
enemy3 = enemy;
break;
}
}
And then in the for-loop:
for (int i = 1; i <= 3; i++) {
setEnemyRef(i, new EnemyShip());
}
You're not instantiating it correctly, try e.g.
EnemyShip variableName = getEnemryRef(i);
variableName = new EnemyShip();
https://docs.oracle.com/javase/tutorial/java/javaOO/objectcreation.html

NullPointerException when trying to return 2D array of objects from a method

I'm working on an assignment where I make a maze from a text file reader. I have made a method which lets me select a text file and convert it to a maze but I'm having trouble extracting the maze from the method. I'm getting a NullPointerException on line 28 which is this: X = Maze[0].length;
I'm stuck on why the method isn't returning my array and also how I can have the method return the StartX and StartY position.
package Innlevering09;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import javafx.application.Application;
import javafx.stage.FileChooser;
import javafx.stage.FileChooser.ExtensionFilter;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
public class MazeGame extends Application {
MazeRoute[][] Maze;
int X;
int Y;
int StartX;
int StartY;
Player Player;
public void start(Stage primaryStage) {
try {
GridPane root = new GridPane();
Player Player = new Player(StartX, StartY);
Maze = FileReader();
X = Maze[0].length;
Y = Maze.length;
root.add(Player.getAppearance(), Player.getXpos(), Player.getYpos());
for(int x = 0; x<X; x++){
for(int y = 0; y<Y; y++){
root.add(Maze[x][y].getAppearance(), x, y);
}
}
Scene scene = new Scene(root, X*10, Y*10);
//scene.setOnKeyPressed(new FileListener(this));
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public MazeRoute[][] FileReader() {
String Text = "";
File File;
int Row;
FileChooser FileChooser = new FileChooser();
FileChooser.setTitle("Open a textfile");
FileChooser.getExtensionFilters().add(new ExtensionFilter("Text Files", "*.txt"));
File = FileChooser.showOpenDialog(null);
try (Scanner FileReader = new Scanner(File)){
X = FileReader.nextInt();
Y = FileReader.nextInt();
Text = FileReader.nextLine();
MazeRoute[][] Maze = new MazeRoute[X][Y];
while (FileReader.hasNext()){
Text = FileReader.nextLine();
for (int i = 0 ; i < X ; i++){
for (Row = 0 ; Row < Y ; Row++) {
char Character = Text.charAt(i);
switch (Character){
case '#':
Maze[i][Row] = new Wall(i, Row);
break;
case ' ':
Maze[i][Row] = new NormalTile(i, Row);
break;
case '-':
Maze[i][Row] = new EndTile(i, Row);
break;
case '*':
Maze[i][Row] = new NormalTile(i, Row);
StartX = i;
StartY = Row;
break;
}Row++;
}
}
}
}catch (FileNotFoundException Error) {
System.out.println("Cannot open file");
Error.printStackTrace();
}
return Maze;
}
public static void main(String[] args) {
launch(args);
}
}
edit:
for the people of the future this is the code where I solved the problem:
public class MazeGame extends Application {
MazeRoute[][] maze;
int X;
int Y;
int startX;
int startY;
Player player = new Player();
public void start(Stage primaryStage){
try{
maze = fileReader();
player.setXpos(startX);
player.setYpos(startY);
GridPane root = new GridPane();
Scene scene = new Scene(root, Color.BLACK);
Player player = new Player();
for(int x = 0; x<X; x++){
for(int y = 0; y<Y; y++){
root.add(maze[x][y].getAppearance(), maze[x][y].getTileXpos(), maze[x][y].getTileYpos());
}
}
root.add(player.getAppearance(), player.getXpos(), player.getYpos());
primaryStage.setTitle("MazeGame");
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public MazeRoute[][] fileReader() throws FileNotFoundException {
String text = "";
File file;
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Open a text file with a maze");
fileChooser.getExtensionFilters().add(new ExtensionFilter("Text Files", "*.txt"));
file = fileChooser.showOpenDialog(null);
Scanner fileScanner = new Scanner(file);
X = fileScanner.nextInt();
Y = fileScanner.nextInt();
text = fileScanner.nextLine();
MazeRoute[][] methodMaze = new MazeRoute [X][Y];
while (fileScanner.hasNext()) {
for (int row = 0 ; row < Y ; row++){
text = fileScanner.nextLine();
for (int i = 0 ; i < X ; i++) {
char character = text.charAt(i);
switch (character) {
case '#':
methodMaze[i][row] = new Wall(i, row);
break;
case ' ':
methodMaze[i][row] = new NormalTile(i, row);
break;
case '-':
methodMaze[i][row] = new EndTile(i, row);
break;
case '*':
methodMaze[i][row] = new NormalTile(i, row);
startX = i;
startY = row;
break;
}
}
}
}
return methodMaze;
}
public static void main(String[] args) {
launch(args);
}
}
the changes I made are the following:
I made a new array with the maze blocks inside of the method to avoid the possibility of any scoping issues.
I swapped the row and i in the for loop meaning that the loop now goes through a full line before incrementing down to the next one.
I moved text = fileScanner.nextLine(); to the inside of the for loop so that it would actually scan the next line.
I changed the for loops to start counting from 0 instead of 1 (stupid mistake I know).
The method FileReader (whose name should start with a lower case letter), returns Maze.
However, this is the property on class level since the local variable with the same name, declared within the try-catch, is out of scope.
This class-level property has not been assigned yet and is therefore equal to null.
It's a scope problem. You are not returning the variable declared in the function "FileReader" because it's declared only in the scope of the while loop. The only variable available for the return is the one declared in the scope of the class.
First, as others have pointed out, Java naming conventions are that all variables, methods, and non-static fields must start with a lower case letter. This is especially important when your variables have the same names as existing Java SE classes. Your code will be much easier to read, and you will not only help yourself, you will get help from people on Stack Overflow more quickly.
In your FileReader method, you have this line:
MazeRoute[][] Maze = new MazeRoute[X][Y];
That line declares a new variable named Maze, which has no relationship to the Maze field of your MazeGame class. All subsequent lines of code are populating that new variable, not the Maze field declared in the MazeGame class.
A variable only exists within the brace-enclosed block where it is declared. In this case, that block is your try block, since new Maze variable is declared inside that try block. Once the the end of that try block is reached, the Maze variable does not exist and its value is eligible for garbage collection.
When your FileReader method reaches its return statement, that Maze variable doesn’t exist, so return Maze; actually refers to the Maze field of the MazeGame class. But that field was never set by your method, since your code was setting a locally defined variable which happened to have the same name. In Java, all object fields are null until set otherwise. So the method returns null.
The easiest way to fix your problem is to avoid defining a new Maze variable. Change this:
MazeRoute[][] Maze = new MazeRoute[X][Y];
to this:
Maze = new MazeRoute[X][Y];

Getting PDF TextObjects with PDFBox

I have a PDF from which I extracted a page using PDFBox:
(...)
File input = new File("C:\\temp\\sample.pdf");
document = PDDocument.load(input);
List allPages = document.getDocumentCatalog().getAllPages();
PDPage page = (PDPage) allPages.get(2);
PDStream contents = page.getContents();
if (contents != null) {
System.out.println(contents.getInputStreamAsString());
(...)
This gives the following result, which looks like something you'd expect, based on the PDF spec.
q
/GS0 gs
/Fm0 Do
Q
/Span <</Lang (en-US)/MCID 88 >>BDC
BT
/CS0 cs 0 0 0 scn
/GS1 gs
/T1_0 1 Tf
8.5 0 0 8.5 70.8661 576 Tm
(This page has been intentionally left blank.)Tj
ET
EMC
1 1 1 scn
/GS0 gs
22.677 761.102 28.346 32.599 re
f
/Span <</Lang (en-US)/MCID 89 >>BDC
BT
0.531 0.53 0.528 scn
/T1_1 1 Tf
9 0 0 9 45.7136 761.1024 Tm
(2)Tj
ET
EMC
q
0 g
/Fm1 Do
Q
What I'm looking for is to extract the PDF TextObjects (as described in par 5.3 of the PDF spec) on the page as java Objects, so basically the pieces between BT an ET (two of 'en on this page).
They should at least contain everything between the brackets preceding 'Tj' as a String, and an x and y coördinate based on the 'Tm' (or a 'Td' operator, etc.). Other attributes would be a bonus, but are not required.
The PDFTextStripper seems to give me either each character with attributes as a TextPosition (too much noise for my purpose), or all the Text as one long String.
Does PDFBox have a feature that parses a Page and provides TextObjects like this that I missed? Or else, if I am to extend PDFBox to get what I need, where should I start? Any help is welcome.
EDIT: Found another question here, that gives inspiration on how I might build what I need. If I succeed, I'll check back. Still looking forward to any help you may have, though.
Thanks,
Phil
Based on the linked question and the hint by mkl yesterday (thanks!), I've decided to build something to parse the tokens.
Something to consider is that within a PDF Text Object, the attributes precede the operator, so I collect all attributes in a collection until I encounter the operator.
Then, when I know what operator the attributes belong to, I move them to their proper locations.
This is what I've come up with:
import java.io.File;
import java.util.List;
import org.apache.pdfbox.pdfparser.PDFStreamParser;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDStream;
import org.apache.pdfbox.util.PDFOperator;
public class TextExtractor {
public static void main(String[] args) {
try {
File input = new File("C:\\some\\file.pdf");
PDDocument document = PDDocument.load(input);
List allPages = document.getDocumentCatalog().getAllPages();
// just parsing page 2 here, as it's only a sample
PDPage page = (PDPage) allPages.get(2);
PDStream contents = page.getContents();
PDFStreamParser parser = new PDFStreamParser(contents.getStream());
parser.parse();
List tokens = parser.getTokens();
boolean parsingTextObject = false; //boolean to check whether the token being parsed is part of a TextObject
PDFTextObject textobj = new PDFTextObject();
for (int i = 0; i < tokens.size(); i++)
{
Object next = tokens.get(i);
if (next instanceof PDFOperator) {
PDFOperator op = (PDFOperator) next;
switch(op.getOperation()){
case "BT":
//BT: Begin Text.
parsingTextObject = true;
textobj = new PDFTextObject();
break;
case "ET":
parsingTextObject = false;
System.out.println("Text: " + textobj.getText() + "#" + textobj.getX() + "," + textobj.getY());
break;
case "Tj":
textobj.setText();
break;
case "Tm":
textobj.setMatrix();
break;
default:
//System.out.println("unsupported operation " + op.getOperation());
}
textobj.clearAllAttributes();
}
else if (parsingTextObject) {
textobj.addAttribute(next);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
In combination with:
import java.util.ArrayList;
import java.util.List;
import org.apache.pdfbox.cos.COSFloat;
import org.apache.pdfbox.cos.COSInteger;
import org.apache.pdfbox.cos.COSString;
class PDFTextObject{
private List attributes = new ArrayList<Object>();
private String text = "";
private float x = -1;
private float y = -1;
public void clearAllAttributes(){
attributes = new ArrayList<Object>();
}
public void addAttribute(Object anAttribute){
attributes.add(anAttribute);
}
public void setText(){
//Move the contents of the attributes to the text attribute.
for (int i = 0; i < attributes.size(); i++){
if (attributes.get(i) instanceof COSString){
COSString aString = (COSString) attributes.get(i);
text = text + aString.getString();
}
else {
System.out.println("Whoops! Wrong type of property...");
}
}
}
public String getText(){
return text;
}
public void setMatrix(){
//Move the contents of the attributes to the x and y attributes.
//A Matrix has 6 attributes, the last two of which are x and y
for (int i = 4; i < attributes.size(); i++){
float curval = -1;
if (attributes.get(i) instanceof COSInteger){
COSInteger aCOSInteger = (COSInteger) attributes.get(i);
curval = aCOSInteger.floatValue();
}
if (attributes.get(i) instanceof COSFloat){
COSFloat aCOSFloat = (COSFloat) attributes.get(i);
curval = aCOSFloat.floatValue();
}
switch(i) {
case 4:
x = curval;
break;
case 5:
y = curval;
break;
}
}
}
public float getX(){
return x;
}
public float getY(){
return y;
}
}
It gives the output:
Text: This page has been intentionally left blank.#70.8661,576.0
Text: 2#45.7136,761.1024
While it does the trick, I'm sure I've broken some conventions and haven't always written the most elegant code. Improvements and alternate solutions are welcome.
I added a version of the Phil response with pdfbox-2.0.1
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.apache.pdfbox.pdfparser.PDFStreamParser;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageTree;
import org.apache.pdfbox.contentstream.operator.Operator;
import org.apache.pdfbox.cos.COSFloat;
import org.apache.pdfbox.cos.COSInteger;
import org.apache.pdfbox.cos.COSString;
public class TextExtractor {
public static void main(String[] args) {
try {
File input = new File("src\\test\\resources\\files\\file1.pdf");
PDDocument document = PDDocument.load(input);
PDPageTree allPages = document.getDocumentCatalog().getPages();
// just parsing page 2 here, as it's only a sample
PDPage page = allPages.get(0);
PDFStreamParser parser = new PDFStreamParser(page);
parser.parse();
List tokens = parser.getTokens();
boolean parsingTextObject = false; // boolean to check whether the token
// being parsed is part of a TextObject
PDFTextObject textobj = new PDFTextObject();
for (int i = 0; i < tokens.size(); i++) {
Object next = tokens.get(i);
if (next instanceof Operator) {
Operator op = (Operator) next;
switch (op.getName()) {
case "BT":
// BT: Begin Text.
parsingTextObject = true;
textobj = new PDFTextObject();
break;
case "ET":
parsingTextObject = false;
System.out.println("Text: " + textobj.getText() + "#" + textobj.getX() + "," + textobj.getY());
break;
case "Tj":
textobj.setText();
break;
case "Tm":
textobj.setMatrix();
break;
default:
System.out.println("unsupported operation " + op);
}
textobj.clearAllAttributes();
} else if (parsingTextObject) {
textobj.addAttribute(next);
} else {
System.out.println("ignore "+next.getClass()+" -> "+next);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
static class PDFTextObject{
private List attributes = new ArrayList<Object>();
private String text = "";
private float x = -1;
private float y = -1;
public void clearAllAttributes(){
attributes = new ArrayList<Object>();
}
public void addAttribute(Object anAttribute){
attributes.add(anAttribute);
}
public void setText(){
//Move the contents of the attributes to the text attribute.
for (int i = 0; i < attributes.size(); i++){
if (attributes.get(i) instanceof COSString){
COSString aString = (COSString) attributes.get(i);
text = text + aString.getString();
}
else {
System.out.println("Whoops! Wrong type of property...");
}
}
}
public String getText(){
return text;
}
public void setMatrix(){
//Move the contents of the attributes to the x and y attributes.
//A Matrix has 6 attributes, the last two of which are x and y
for (int i = 4; i < attributes.size(); i++){
float curval = -1;
if (attributes.get(i) instanceof COSInteger){
COSInteger aCOSInteger = (COSInteger) attributes.get(i);
curval = aCOSInteger.floatValue();
}
if (attributes.get(i) instanceof COSFloat){
COSFloat aCOSFloat = (COSFloat) attributes.get(i);
curval = aCOSFloat.floatValue();
}
switch(i) {
case 4:
x = curval;
break;
case 5:
y = curval;
break;
}
}
}
public float getX(){
return x;
}
public float getY(){
return y;
}
}
}

writing Jtextfield string data into an arraylist, and reading same data from arraylist to Jtextfields

I have been scouring the internet for answers to my problem. I have found some good advice and have changed my original code, but I am yet to discover the answer to my initial problem.
I am trying to take string data from a series of Jtextfields and writing them to an arraylist, and then in turn taking the written data from the arraylist and transfering it to the same text fields.
public class Form extends javax.swing.JFrame {
public ArrayList<Personal> personalList;
public ArrayList<Business> businessList;
public ArrayList<Personal> displayPersonalList;
public ArrayList<Business> displayBusinessList;
public Form() {
initArrayLists();
}
private void initArrayLists(){
personalList = new ArrayList<Personal>();
businessList = new ArrayList<Business>();
displayPersonalList = new ArrayList<Personal>();
displayBusinessList = new ArrayList<Business>();
}
this is my submit button that writes to the arraylists.
private void submitButtonActionPerformed(java.awt.event.ActionEvent evt)
{
if (contactTypeLabel.getText().equals("Personal Contact")){
Personal p = new Personal();
p.first = firstNameTF.getText();
p.last = lastNameTF.getText();
p.address = addressTF.getText();
p.s = stateTF.getText();
p.zip = zipTF.getText();
p.phone = phoneTF.getText();
p.email = emailTF.getText();
personalList.add(p);
Personal d = new Personal();
d.first = firstNameTF.getText();
displayPersonalList.add(p);
resetTextFields();
}else if (contactTypeLabel.getText().equals("Business Contact")){
Business b = new Business();
b.first = firstNameTF.getText();
b.last = lastNameTF.getText();
b.address = addressTF.getText();
b.s = stateTF.getText();
b.zip = zipTF.getText();
b.phone = phoneTF.getText();
b.email = emailTF.getText();
businessList.add(b);
Business d = new Business();
d.first = firstNameTF.getText();
displayBusinessList.add(d);
resetTextFields();
}
}
here is the code to change to display mode, with a combobox that should populate for accessing the arraylist to fill the textfields with selected data
private void displayPersonalButtonActionPerformed(java.awt.event.ActionEvent evt)
{
personalFieldViewer();
submitButton.setVisible(false);
displayComboBox.setVisible(true);
clearTextFields();
for (Object item : displayPersonalList) {
displayComboBox.addItem(item);
}
}
this is the code for the combobox action and code to fill the text fields
private void displayComboBoxActionPerformed(java.awt.event.ActionEvent evt)
{
int x;
switch (displayComboBox.getSelectedIndex()){
case 0:
for (x = 0; x < x + 8; x ++) {
switch (x){
case 0 :firstNameTF.setText(personalList.get(x).toString());
break;
case 1 :lastNameTF.setText(personalList.get(x).toString());
break;
case 2 :addressTF.setText(personalList.get(x).toString());
break;
case 3 :stateTF.setText(personalList.get(x).toString());
break;
case 4 :zipTF.setText(personalList.get(x).toString());
break;
case 5 :phoneTF.setText(personalList.get(x).toString());
break;
case 6 :dobTF.setText(personalList.get(x).toString());
break;
case 7 :emailTF.setText(personalList.get(x).toString());
break;
}
}
break;
case 1:
for (x = 8; x < x + 8; x ++) {
switch (x){
case 8 :firstNameTF.setText(personalList.get(x).toString());
break;
case 9 :lastNameTF.setText(personalList.get(x).toString());
break;
case 10 :addressTF.setText(personalList.get(x).toString());
break;
case 11 :stateTF.setText(personalList.get(x).toString());
break;
case 12 :zipTF.setText(personalList.get(x).toString());
break;
case 13 :phoneTF.setText(personalList.get(x).toString());
break;
case 14 :dobTF.setText(personalList.get(x).toString());
break;
case 15 :emailTF.setText(personalList.get(x).toString());
break;
}
}
break;
case 2:
for (x = 16; x < x + 8; x ++) {
switch (x){
case 16 :firstNameTF.setText(personalList.get(x).toString());
break;
case 17 :lastNameTF.setText(personalList.get(x).toString());
break;
case 18 :addressTF.setText(personalList.get(x).toString());
break;
case 19 :stateTF.setText(personalList.get(x).toString());
break;
case 20 :zipTF.setText(personalList.get(x).toString());
break;
case 21 :phoneTF.setText(personalList.get(x).toString());
break;
case 22 :dobTF.setText(personalList.get(x).toString());
break;
case 23 :emailTF.setText(personalList.get(x).toString());
break;
}
}
break;
}
}
here are the classes that hold the variables for the arraylists.
public class Contacts {
public String first, last, address, s, zip, phone, email;
}
public class Personal extends Contacts{
public String dob;
}
public class Business extends Contacts{
public String title, organization;
}
when I alternately try to fill the arraylists with *.add(textfield.getText()); Java will not allow this as well as using variables first=firstNameTF.getText(); then *.add(first); I get the same error message...
Please try to refrain from being negative, and I have read the API regarding arraylists. Thank you.
Your arraylist declarations has type either Personal or Business. So these list cant add a string value. So when you say personalList.add(textfield.getText()); its actually trying to add String object to a list that can contain only Personal object.
Secondly the for loop inside displayComboBoxActionPerformed() method results in an infinite loop. for (x = 0; x < x + 8; x ++). Insted of having different for loops and switch statements you could do something like
private void displayComboBoxActionPerformed(java.awt.event.ActionEvent evt) {
if(displayComboBox.getSelectedIndex() > -1){
int start = displayComboBox.getSelectedIndex() * 8;
for (int x = start; x < start + 8; x ++) {
firstNameTF.setText(personalList.get(x).toString());
}
}
}

random image in android

I have Images in drawable and I shuffle these images But I want that R.drawable.a this image come 5 time and this R.drawable.b come 10 time but in my code image come again and again.
My question is that I want that image a R.drawable.a come 5 time after that image R.drawable.a remove from list and other images come on shuffling all images .
But in mean time image a R.drawable.a come n time
public void addNewImageToScreen() {
//array of all drawable id's
int pics[] = { R.drawable.a, R.drawable.b, R.drawable.c, ...etc...};
Random rand = new Random();
int pos = rand.nextInt(pics.length);
addNewImageToScreen(pics[pos]);
}
Can Anybody help me how this is possible?
You need to remove the one you have shown earlier
addNewImageToScreen(pics[pos]);
int arraySize=pics.length;
pics[pos] = pics[--arraySize];
Edit:
or use this logic
ArrayList picsarr=Arrays.asList(pics);
for(int i=0;i<picsarr.size;i++)
{
Collections.shuffle(picsarr);
addNewImageToScreen(picsarr.get[i]);
picsarr.remove(i);
}
Try this code i think it will help you but i am not sure in my case it works fine
Random random = new Random( System.currentTimeMillis() );
List<Integer> generated = new ArrayList<Integer>();
for (int i = 0; i < imageViews.length; i++) {
int v = imageViews[i];
int next = random.nextInt( 15 ) + 1;
if ( !generated.contains( next ) ) {
generated.add( next );
ImageView iv = (ImageView) findViewById( v );
iv.setImageResource( images[next] );
}
else {
i--;
}
}
After some discussion with this fella it seems that this is what he wants:
private ArrayList<Integer> mDrawableIds = new ArrayList<Integer>();
private void populateList() {
mDrawableIds.add(R.drawable.a);
mDrawableIds.add(R.drawable.b);
mDrawableIds.add(R.drawable.c);
}
private int returnImageResource(int buttonClickCount) {
int imageResource = -1;
switch (buttonClickCount) {
case 1:
imageResource = mDrawableIds.get(0);
break;
case 2:
imageResource = mDrawableIds.get((int) (Math.random() * mDrawableIds.size()));
break;
case 3:
imageResource = mDrawableIds.get(1);
break;
// more cases here
case 10:
imageResource = mDrawableIds.get((int) (Math.random() * mDrawableIds.size()));
mDrawableIds.remove(0);
break;
}
return imageResource;
}
I left out some code but this should get you started. What you lacked was an ArrayList which you can remove entries from dynamically.

Categories