Java, 2D String Array Filled from JTextFields - java

I am creating a commercial software and got stuck in place, where I need to fill an Array with information from multiple JTextBox fields.
I created an Array -
public String[][] BookAttributes = new String[BookRows][BookLines];
I want to save information added by User from following JTextFields in [BookLines] column for each book, which should auto-increment every time when new book is added to stock.
private JTextField tfBookName;
private JTextField tfBookCost;
private JTextField tfBookYearOfPublication;
private JTextField tfBookPublishingHouse;
private JTextField tfBookISBN;
private JTextField tfBookAuthor;
private JTextField tfBookNrOfPages;
Unfortunately, I cannot find a solution how to put this all together.
Any Help appreciated.
Thank you!

If I understood you correctly then you are looking to save the Book information like Name, Cost etc. to an array.
But, in the above case you are creating a 2-D String Array which looks something like this:
Location (0,0) of array -> "foo"
Location (0,1) of array -> "bar"
...
...
What you actually need is a class say, Book which can hold the information regarding the different attributes. Something like as follows:
public class Book {
private String bookName;
private String bookCost;
private String bookYearOfPublication;
private String bookPublishingHouse;
private String bookISBN;
private String bookAuthor;
private String bookNrOfPages;
/* Constructor, Getter, Setters */
...
}
Next you can create an array of this class like this:
int bookRows = 100;
Book[] booksInfo = new Book[bookRows];
And simply code a for loop for stroing the different book details as follows:
for(int i = 0; i < bookRows; i++) {
Book book = new Book();
book.setBookName(tfBookName);
...
...
booksInfo[i] = book;
}
You can further override the toString() method of the Book class if you want to print the different attributes of any book by simply using System.out.println(...).
Here is the code snippet:
#Override
public String toString() {
return new StringBuilder().append("BookName: ").append(bookName)
.append(" | Book Cost: ").append(bookCost).toString();
}

Related

How get elements from an ArrayList based by multiple conditions?

I'm creating an interface that manage the booking of Cinema tickets in different weeks/theatres.
I have a Film Class:
public class Film {
private String title;
private Double price;
private String ageRestriction;
private double rating;
private String genre;
private String location;
private String screenDay;
}
A FilmList class that create and store all the Films in an ArrayList:
public class FilmList {
private ArrayList <Film> filmArrayList;
public FilmList (){
this.filmArrayList = new ArrayList<>();
}
public void addFilm(Film films){
this.filmArrayList.add(films);
}
And this is the graphic unit interface. What I'm trying to do is to catch in the ArrayList just one element based on two condition:
The Week and the Theatre selected from the user and also add a way for check that there's just one element on the list from the chosen parameters. This is important because each film instance will be called and "setted" on the Label of the FXML file (and because I'm thinking to implement an interface for add films in the ArrayList).
Thank's everyone.
OK, so in your example it would be something like following:
//try to find any movie that suits two predicates, 1st - that it's price is greater than 30( this is random number, you can put a value from your textfield here ) and 2nd - that it's title contains Spiderman ( again, put a value from your textfield title search here for your need )
Optional<Film> movie = listOfMovies.stream().filter(i -> i.getPrice() > 30 && i.getTitle.contains("Spiderman")).findAny();
// if any movie has been found to suits provided criterias
if(movie.isPresent())
{
//print it on screen, note method get()
//again this is just for example here, in your code,
// you can do with this result whatever you like
// for example show all data about that movie on screen
System.out.println("---->" +movie.get());
}
else
{
// if not found do nothing
System.out.println("Nothing found...");
}
More about Optional can be found here.

Can not display contents of Arraylist n JTable

I can't figure this out (have been trying to fix this for the past 2-3 hours).
I would like to display the contents of an arraylist, but they do not appear in the table and also there are NO errors, they simply do not appear. Here is my code:
private class examinations{
private int id;
private int candidate_id;
private String date;
private String exam;
private String examNumber;
public examinations(int id, int student_id, String date, String exam, String examNumber) {
this.id = id;
this.student_id = student_id;
this.date = date;
this.exam= exam;
this.examNumber= examNumber;
}
public ArrayList ListExams(){
ArrayList<exams> list = new ArrayList<exams>();
return list;
}
public void addRollToTable(){
DefaultTableModel model = (DefaultTableModel)tableExams.getModel();
ArrayList<exams> list = ListExams();
Object rowData[] = new Object[5];
for(int i = 0; i < list.size(); i++) {
rowData[0] = list.get(i).id;
rowData[1] = list.get(i).student_id;
rowData[2] = list.get(i).date;
rowData[3] = list.get(i).exam;
rowData[4] = list.get(i).examNumber;
model.addRow(rowData);
}
}
}
I tested this loop and the variables coming out of the other list are there, so a System.out.println(list.get(i).exam); will display the correct thing i typed. However the table will NOT display whatever I add in the rowData. It gives, again, no errors. Let me show you the DefaultTableModel code. This code is in the private void initComponents() of my class...
Object [][] data = {};
String[] columnNames = {"Id", "Student_Id", "Date", "Exam",
"Exam_number"};
tableExams= new javax.swing.JTable();
DefaultTableModel model = new DefaultTableModel(data, columnNames);
tableExams.setModel(model);
tableExams.setCursor(new java.awt.Cursor(java.awt.Cursor.TEXT_CURSOR));
jScrollPane4.setViewportView(tableExams);
I've been reading this: DefaultTableModel Class Overview But I still can't find where I am going wrong... Could anyone give a tip?
First of all learn and use Java naming conventions:
Classs names SHOULD start with an upper case character. Can you show me a class in the JDK that does not?
Method should should NOT start with an upper case character. Again, can you show me a method in the JDK the does?
Learn by example and don't make up your own conventions.
so a System.out.println(list.get(i).exam); will display the correct thing i typed
I don't know how this is possible. Your code is as follows:
a) First, you retrieve the ArrayList from the "listExams() method.
ArrayList<exams> list = ListExams();
b) But in the "listExams()" method all you do is create an empty ArrayList.
ArrayList<exams> list = new ArrayList<exams>();
So you are missing the logic that actually adds data to the ArrayList.
Based on the logic provided, you don't even need the ArrayList. Just take the data from the Examination class and add it to the TableModel:
Object rowData[] = new Object[5];
rowData[0] = id;
rowData[1] = student_id;
rowData[2] = date;
rowData[3] = exam;
rowData[4] = examNumber;
model.addRow(rowData);
For a different solution you could create a custom TableModel to hold your "Examination" objects. Check out Row Table Model for a step-by-step example of how this can be done.
OK, I solved it, even though this was just a work around, I'd accept it.
All I did was use this.setVisible(false) and then entered the information in the other JFrame. Clicking add, i make an object of the first JFrame, passed all the variables, used this.dispose() and then called .setVisible(true) to return to the table, which displayed the information. LOL that was a long testing and re-writing of code to actually realize it was something that small...
I am sorry, I did not know where the actual problem was, and yeah thanks a lot for that simple suggestion there camickr. I tried it in the same JFrame and it worked, then I tried it between 2 JFrames and I realized the JFrame with the table DID NOT update the table. repaint() also didn't work. You quite literally helped me out with that small tip, which is all i needed. THANKS!!!!!!

simplifying java array layout

is there any other way of applying this table to array rather than creating 31 of them?
The layout looks like:
state_name|year|crimetype1|crimetype2|place|count|
row1: state1|2001|murder|knife|home|5|
row2: state1|2001|murder|axe|home|2|
row3: state2|2001|robbery|baseball|shop|1|
and so on for 31 different states.
I thought of creating 31 arrays for each state with 5 rows but is there any other way of making it simpler?
Simply put: objects. That way, you will not have to have nested arrays.
Make a class:
public class Crime{
private int year;
private String state;
private String crimeType1, crimeType2;
private String place;
private int count;
//And then you'd have some useful stuff here...
}
Besides this, I don't think you should combine the 31 values anymore - they are 31 separate, independent occurrences.
First, create a Crime object which can represent a single row in that collection. Let's make it naturally comparable against itself based on the state.
public class Crime implements Comparable<Crime> {
private String state;
private Year year;
private String crimeType1;
private String crimeType2;
private String place;
private int count;
public int compareTo(Crime other) {
return state.compareTo(other.state);
}
}
I leave the construction of this object as an exercise for the reader.
Next, you'll want to add the results of that value to a list.
List<Crime> crimes = new ArrayList<>();
// In a loop reading the file
crimes.add(crime);
At this point your work is pretty much done; if you want to get the crimes by a specific state, you can use the Stream API to filter based on that.
It is better to create class Crime as follows
getHeader() returns header and getRow will return the row . (or toString)
public class Crime {
String stateName;
String year;
//...
public static String getHeader(){
//you can improve this
return "state_name|year|crimetype1|crimetype2|place|count|";
}
public String getRow(){
return stateName + "|" + year +"|" ...
}
public static void main(String[] args) {
List<Crime> state = new ArrayList<>(31);
//or
List<Crime> state = Arrays.asList(new Crime[] {
new Crime("ST","2004",..),...
});
}
}
as KevinO pointed if you are coding OO language it is good to think in OO way otherwise there no point of using java.
Create a Crime class with all the values except state and then a Map
Map<String,ArrayList<Crime>> multiMap = new HashMap<String,ArrayList<Crime>>();
Here String is state name and the ArrayList for all the crimes in that state, So at the end there will be 31 keys (Here we are using state as unique keys) in muliMap Object.
So later you no need to filter statewise crimes, all you need to do is
ArrayList<Crime> state1Crimes = multiMap.get("state1");
Simple and straight forward.

Java NullPointerException when referencing object array

I have the following program:
class Books
{
String title;
String author;
}
class BookTestDrive
{
public static void main(String [] args)
{
Books [] myBooks = new Books[3];
int x = 0;
myBooks[0].title = "The Grapes of Java";
myBooks[1].title = "The Java Gatsby";
myBooks[2].title = "The Java Cookbook";
myBooks[0].author = "bob";
myBooks[1].author = "sue";
myBooks[2].author = "ian";
while (x < 3)
{
System.out.print(myBooks[x].title);
System.out.print(" by ");
System.out.println(myBooks[x].author);
x = x + 1;
}
}
}
However, it gives me the following error when I execute it:
Exception in thread "main" java.lang.NullPointerException
at BookTestDrive.main(Books.java:14)
I am new to Java. The code looks legitimate from my C/C++ experience...How to resolve this problem?
The issue is that you have only created the array of books in the following lines -
Books [] myBooks = new Books[3];
You still need to initialize each element in the array to a book object before accessing them.
An example code would look like -
Books [] myBooks = new Books[3];
int x = 0;
myBooks[0] = new Books();
myBooks[0].title = "The Grapes of Java";
You need to do this for all elements in your array.
I second the answer from #AnandSKumar (it is the direct answer to the problem after all), but because it is a matter of beauty, I could not leave without making following few changes:
public class Play {
static public class Book {
final public String title;
final public String author;
public Book(String title,String author) {
this.title = title;
this.author = author;
}
#Override
public String toString() {
return "\""+title+"\" by "+author;
}
}
public static void main(String [] args)
{
Book [] books = new Book[] {
new Book("The Grapes of Java","bob"),
new Book("The Java Gatsby","sue"),
new Book("The Java Cookbook","ian"),
};
for (Book book:books) {
System.out.println(book);
}
}
}
You can initialize in-line the content of your array
If you represent 'a single book' then we should name the class representing it as Book and not Books to avoid confusion.
We can enhance the Book class with an improved toString(), and use that instead.
There is a enhanced for iterator to loop over your array.
Note that the third position book in the array, also ends with a comma, although there is no element following it. This could have been a mistake, but it this case it was a deliberate choice. Makes it easier to copy-paste into next elements without introducing errors, as the Java syntax allows for it.
Because once a book is created, title and author should not change anymore, it might be good to design the Book class to be 'Immutable'. For this reason a constructor was added, and the title and author fields set as final. You could also consider making them private, and provide getters.

Can I put a String in an Arraylist when a object is created?

I want to make a program where you can name a String("weapon" for example)and then add that String to a ArrayList. But without typing it yourself like:
MyArrayList.add(Egg); //for example
So that the new Object automatically add to the Arraylist.
So what I did, I created an Arraylist that will hold the weapon names. I made a method, where you can "make" in the main class a object with the weapon name.But how do i make something that when a object (in the main class)is created, it automatically add it self to the arraylist.
(Sorry for bad explaining, I'm from The Netherlands so... If it's a bad explaining please tell me so i can improve it)
Maybe I completely misunderstand it, but do you want to do something like this?
private ArrayList<YourObject> list;
public YourMainClass(){
list = new ArrayList<YourObject>();
}
public void onAdd(String weaponName){
list.add(new YourObject("weaponName")); // <- this being your issue
}
With YourObject being something like:
public class YourObject
{
private String name;
public YourObject(String n){
setName(n);
}
public void setName(String n){
// Perhaps an if-else to check if n isn't null, nor emtpy?
name = n;
}
public String getName(){
return name;
}
}
Based on my interpretation of your problem, you want to have the user create a weapon name and add it to the ArrayList without having to manually add the code to add it?
A basic way to get String input from a user:
Scanner inputscan = new Scanner(System.in); //reads input from command line
String weapon = inputscan.nextLine(); //waits for user input
MyList.add(weapon);
That way, every time you call the "make" method with that code in it, it will prompt the user to type a weapon name, then the weapon name gets stored in the array.
I think you want to initialize the List with an object in it:
Try using an instance block, like this:
List<String> list = new ArrayList<String>() {{
add("Egg");
}};
Add the command to add the object to the collection in the constructor.( But this ill advise)
You can create an auxiliary class that will create that object and label to the collection.
class WeaponFactory
{
Collection c;
public WeaponFactory(Collection coll){c=coll;}
public Weapon makeWeapon(String text) // Makes sense when the object is not String , like a Weapon class which also contains stats or something
{
Weapon w = new Weapon(text)
c.add(w);
return w;
}
}
class Weapon
{
String name;
public Weapon(String text)
{
name = text;
}
}

Categories