EDIT
I've cleaned up the .equals method for string equality and changed the ContactsCollection initialization to:
public static ArrayList<Contact> contactList = new ArrayList<Contact>();
I've also changed the action performed method in hopes that 'Display contacts' would show more than one contact.
if (contactInput.equals("Display contacts"))
{
ContactsCollection.read();
for (int i = 0; i < contactList.size(); i++)
{
contact = (Contact)contactList.get(i);
for (int j =0; j < contactList.size(); j++)
{
textArea.append(contact.getName() + "," + contact.getNumber() + "\n");
}
}
}
Ultimately the .dat file is written but does not contain any data that is added through the GUI.
END EDIT
I am writing a mock cellphone GUI that acts as a very basic contacts manager. There are several other classes that do not deal with the ArrayList that are working as intended.
When attempting to add a contact to the file I receive a null pointer exception at line 13 of the ContactsCollection class:
for (int i = 0; i < contactList.size(); i++)
and line 93 of the Contacts (GUI) class:
contactList.add(contact);
I have a feeling that I did something wrong when coding the Contacts and ContactsCollection classes. I'm hoping the program to run as follows: The user clicks add contact and enters the information which becomes an object Contact and is added to the contactList ArrayList and written (serialized) to a file "contactList.dat". When the user clicks display contacts the file is read in and each contact is displayed in GUI.
I think that there are several issues with the way I set up the ArrayList, but I think I'm very close to having the program run as I had hoped. Any help is greatly appreciated!
Contacts class:
import java.util.*;
import java.io.*;
public class Contact implements Serializable
{
public static final long serialVersionUID = 42L;
public String name, number;
Contact()
{
name = "No name";
number = "No number";
}
Contact (String theName, String theNumber)
{
this.name = theName;
this.number = theNumber;
}
public void setName(String aName)
{
this.name = aName;
}
public void setNumber(String aNumber)
{
this.number =aNumber;
}
public String getName()
{
return name;
}
public String getNumber()
{
return number;
}
public String toString()
{
return name + ": " + number;
}
public boolean equals(Contact other)
{
if (name.equals(other.getName()) && number.equals(other.getNumber()))
{
return(true);
}
else
{
return(false);
}
}
}
Contacts Collection class
import java.io.*;
import java.util.*;
class ContactsCollection
{
public static ArrayList<Contact> contactList;
public static void write()
{
try
{
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("contactList.dat"));
for (int i = 0; i < contactList.size(); i++)
{
out.writeObject(contactList.get(i));
}
out.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
public static void read()
{
contactList = new ArrayList<Contact>();
try
{
ObjectInputStream in = new ObjectInputStream(new FileInputStream("contactList.dat"));
Contact temp;
while (in.available()!=0)
{
temp = (Contact)in.readObject();
contactList.add(temp);
}
in.close();
}
catch(FileNotFoundException e)
{
e.printStackTrace();
}
catch(IOException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
Contacts (GUI) class
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.Timer;
import java.util.*;
class Contacts extends JFrame implements ActionListener, WindowListener
{
public static final int WIDTH = 400;
public static final int HEIGHT = 600;
public static final int SMALL_WIDTH = 200;
public static final int SMALL_HEIGHT = 100;
private static final Dimension stdBtn = new Dimension(150, 50);
JPanel centerPanel, northPanel, southPanel;
ImageIcon icon;
JLabel picture;
JButton addContact, displayContacts;
JScrollPane scroll;
JTextArea textArea;
Clock clock;
Background background;
Contact contact;
ArrayList<Contact> contactList;
public Contacts()
{
super("Contacts");
this.setLayout(new BorderLayout());
this.setSize(WIDTH, HEIGHT);
this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
addWindowListener(this);
this.setLocationRelativeTo(null);
centerPanel = new JPanel();
northPanel = new JPanel();
southPanel = new JPanel();
centerPanel.setBackground(Color.BLACK);
southPanel.setBackground(Color.BLACK);
clock = new Clock();
northPanel.add(clock);
icon = new ImageIcon("ContactsBackground.jpg");
picture = new JLabel(icon);
centerPanel.add(picture);
textArea = new JTextArea("", 10, 30);
textArea.setEditable(false);
JScrollPane scroll = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
centerPanel.add(scroll);
JButton displayContacts = new JButton("Display contacts");
displayContacts.addActionListener(this);
southPanel.add(displayContacts);
JButton addContact = new JButton("Add contact");
addContact.addActionListener(this);
southPanel.add(addContact);
this.add(northPanel, BorderLayout.NORTH);
this.add(centerPanel, BorderLayout.CENTER);
this.add(southPanel, BorderLayout.SOUTH);
setResizable(false);
}
public void actionPerformed(ActionEvent e)
{
contactList = new ArrayList<Contact>();
JButton source = (JButton)e.getSource();
String contactInput = source.getText();
if (contactInput == "Display contacts")
{
ContactsCollection.read();
for (int i = 0; i < contactList.size(); i++)
{
contact = (Contact)contactList.get(i);
textArea.setText(contact.getName() + "," + contact.getNumber() + "\n");
}
}
if (contactInput == "Add contact")
{
String name = JOptionPane.showInputDialog(null, "Enter Name");
String number = JOptionPane.showInputDialog(null, "Enter Number");
contact = new Contact(name, number);
contactList.add(contact);
ContactsCollection.write();
}
}
public void windowOpened(WindowEvent e)
{}
public void windowClosing(WindowEvent e)
{
this.setVisible(false);
background = new Background();
background.setVisible(true);
}
public void windowClosed(WindowEvent e)
{}
public void windowIconified(WindowEvent e)
{}
public void windowDeiconified(WindowEvent e)
{}
public void windowActivated(WindowEvent e)
{}
public void windowDeactivated(WindowEvent e)
{}
}
Change
public static ArrayList<Contact> contactList;
to
public static ArrayList<Contact> contactList = new ArrayList<>();
in your version contactList is null because you never initialize it and in the write() method you are trying to call size() on it.
Also, there are some serious flaws in your GUI class (in the actionPerformed() method), read this question to fix them: How do I compare strings in Java?
Also remember that textArea.setText(...) will set the complete text for the textArea, so because this is in a loop in your code, the textArea will contain the output of the last iteration of that loop only. In your case it will be only the last contact.
Related
I'm writing a simple Trivia game and I ran into a problem where the question string won't display
In my frame I'm using border layout with "new game" and "end game" on the bottom (South) and my Trivia panel in the center.
The Trivia panel is made of grid layout with 2 rows and 1 column with the 4 answers on the bottom half and on the upper half I used another panel with border layout with the question string in the center and the score in the east.
It should look like this:
However all of the components display except for the question string.
My paintComponent is:
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setFont(font);
g.drawString(tf,0,0);
}
where tf is my string and my Trivia panel code is:
public TriviaPanel(){
score = 0;
scoreString = new JTextField();
scoreString.setFont(font);
questionPanel = new JPanel();
questionPanel.setLayout(new BorderLayout());
questionPanel.add(scoreString,BorderLayout.EAST);
this.setLayout(new GridLayout(2,1));
pool = null;
try {
pool = new Pool();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
question = pool.getQuestion();
String[] answers = question.shuffle();
tf = question.getQuestion();
this.add(questionPanel);
answersPanel = new JPanel();
answersPanel.setLayout(new GridLayout(2,2));
buttons = new JButton[NUM_OF_ANSWERS];
for (int i = 0; i < NUM_OF_ANSWERS; i++) {
buttons[i] = new JButton(answers[i]);
answersPanel.add(buttons[i]);
buttons[i].addActionListener(lis);
}
this.add(answersPanel);
scoreString.setText("Score: "+score+"/"+pool.getIterator()*CORRECT);
}
where pool is used to hold my pool of questions.
When I debugged the code I see the tf string being updated to the question string but it won't display.
Is it because of the coordinates?
Any insights would be greatly appreciated.
[Edit] Although not finished but full code below:
import java.util.Arrays;
import java.util.Collections;
public class Question {
private final int NUM_OF_ANSWERS = 4;
private String question;
private String[] answers = new String[NUM_OF_ANSWERS];
private final int CORRECT_ANSWER = 0;
public Question(String qu, String an, String dm1, String dm2, String
dm3){
question = qu;
answers[0] = an;
answers[1] = dm1;
answers[2] = dm2;
answers[3] = dm3;
}
public String getCorrectAnswer() {
return answers[CORRECT_ANSWER];
}
public String getQuestion(){
return question;
}
public String[] getAnswers(){
return answers;
}
public String toString(){
String str = question;
for (int i = 0; i<4; i++)
str+=" "+answers[i];
str+="\n";
return str;
}
public String[] shuffle(){
String[] shuffled = new String[NUM_OF_ANSWERS];
for (int i=0;i<NUM_OF_ANSWERS;i++)
shuffled[i]=answers[i];
Collections.shuffle(Arrays.asList(shuffled));
return shuffled;
}
}
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Scanner;
public class Pool {
private ArrayList<Question> questions = new ArrayList<>();
private Scanner input = new Scanner(new File("src/trivia.txt"));
private static int iterator = 0;
public Pool() throws FileNotFoundException {
while (input.hasNext()){
String q = input.nextLine();
String a = input.nextLine();
String d1 = input.nextLine();
String d2 = input.nextLine();
String d3 = input.nextLine();
Question question = new Question(q,a,d1,d2,d3);
questions.add(question);
}
Collections.shuffle(questions);
//System.out.println(questions);
}
public Question getQuestion(){
Question q = questions.get(iterator);
iterator++;
return q;
}
public int getSize(){
return questions.size();
}
public static int getIterator() {
return iterator;
}
}
import javax.swing.*;
import java.awt.*;
public class GameFrame extends JFrame {
private JButton restart, finish;
private JPanel buttons;
public GameFrame(){
super("Trivia");
TriviaPanel tp = new TriviaPanel();
this.setLayout(new BorderLayout());
this.add(tp,BorderLayout.CENTER);
restart = new JButton("New game");
finish = new JButton("End game");
buttons = new JPanel();
buttons.add(restart);
buttons.add(finish);
this.add(buttons,BorderLayout.SOUTH);
this.setSize(1000,600);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args) {
GameFrame gf = new GameFrame();
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileNotFoundException;
import java.util.concurrent.TimeUnit;
public class TriviaPanel extends JPanel {
private TimerListener tl = new TimerListener();
private Timer timer = new Timer(10000,tl);
private static int score;
private JTextField scoreString;
private final int CORRECT = 10, INCORRECT = 5;
private JButton[] buttons;
private Pool pool;
private Question question;
private JButton pressed;
private final int NUM_OF_ANSWERS = 4;
private Listener lis = new Listener();
//private JPanel questionPanel;
private JPanel answersPanel;
private String tf;
private Font font = new Font("Serif",Font.BOLD,24);
private JTextField tf2 = new JTextField();
private QuestionPanel questionPanel;
public TriviaPanel(){
score = 0;
scoreString = new JTextField();
scoreString.setFont(font);
questionPanel = new QuestionPanel();
//questionPanel.setLayout(new BorderLayout());
//questionPanel.add(scoreString,BorderLayout.EAST);
this.setLayout(new GridLayout(2,1));
pool = null;
try {
pool = new Pool();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
question = pool.getQuestion();
String[] answers = question.shuffle();
tf = question.getQuestion();
//tf2.setText(question.getQuestion());
//questionPanel.add(tf2,BorderLayout.CENTER);
this.add(questionPanel);
answersPanel = new JPanel();
answersPanel.setLayout(new GridLayout(2,2));
buttons = new JButton[NUM_OF_ANSWERS];
for (int i = 0; i < NUM_OF_ANSWERS; i++) {
buttons[i] = new JButton(answers[i]);
answersPanel.add(buttons[i]);
buttons[i].addActionListener(lis);
}
this.add(answersPanel);
timer.start();
scoreString.setText("Score: "+score+"/"+pool.getIterator()*CORRECT);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
questionPanel.repaint();
}
private void next(){
Question q = pool.getQuestion();
question=q;
tf = q.getQuestion();
String[] answers = q.shuffle();
for (int i = 0; i < NUM_OF_ANSWERS; i++)
buttons[i].setText(answers[i]);
}
private void gameOver(){
JOptionPane.showConfirmDialog(null,
"Score: "+score, "Select an Option...", JOptionPane.YES_NO_CANCEL_OPTION);
}
private void check(String guess) {
timer.stop();
String answer = question.getCorrectAnswer();
if (guess.equals(answer)) {
score += CORRECT;
tf = "Correct!!!";
} else {
score -= INCORRECT;
tf = "Wrong answer";
}
scoreString.setText("Score: "+score+"/"+pool.getIterator()*CORRECT);
repaint();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private class QuestionPanel extends JPanel{
public QuestionPanel(){
this.setLayout(new BorderLayout());
this.add(scoreString,BorderLayout.EAST);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setFont(font);
g.drawString(tf,0,200);
}
}
private class Listener implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
pressed = (JButton) e.getSource();
String guess = pressed.getText();
check(guess);
if (pool.getIterator() < pool.getSize()) {
timer.restart();
next();
}
else
gameOver();
}
}
private class TimerListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
timer.stop();
score-=INCORRECT;
scoreString.setText("Score: "+score+"/"+pool.getIterator()*CORRECT);
repaint();
timer.restart();
next();
}
}
}
Start by getting rid of
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
questionPanel.repaint();
}
Seriously this is just dangerous and could set you for a endless loop which will consume your CPU cycles
Next, I modified your QuestionPanel so the text is actually rendered somewhere within the realms of probability ...
private class QuestionPanel extends JPanel {
public QuestionPanel() {
this.setLayout(new BorderLayout());
this.add(scoreString, BorderLayout.EAST);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setFont(font);
FontMetrics fm = g.getFontMetrics();
int y = ((getHeight() - fm.getHeight()) / 2) + fm.getAscent();
g.drawString(tf, 10, y);
}
}
But seriously, why aren't you just using a JLabel?
Now, any time tf changes, you need to call QuestionPanel's repaint method.
So, that's in the next and check(String) methods.
And finally (for now), you should never, ever do...
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
inside the context of the event dispatching thread. This is stopping the repaints from been processed, so, for one whole second, nothing will change.
If you want to stop the user for a second, disable the buttons and/or other controls and use another Swing Timer (for simplicity)
This is demonstrated in this self contained, compilable and runnable example...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
GameFrame frame = new GameFrame();
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class GameFrame extends JFrame {
private JButton restart, finish;
private JPanel buttons;
public GameFrame() {
super("Trivia");
TriviaPanel tp = new TriviaPanel();
this.setLayout(new BorderLayout());
this.add(tp, BorderLayout.CENTER);
restart = new JButton("New game");
finish = new JButton("End game");
buttons = new JPanel();
buttons.add(restart);
buttons.add(finish);
this.add(buttons, BorderLayout.SOUTH);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
public static class TriviaPanel extends JPanel {
// private TimerListener tl = new TimerListener();
// private Timer timer = new Timer(10000, tl);
private static int score;
private JTextField scoreString;
private final int CORRECT = 10, INCORRECT = 5;
private JButton[] buttons;
private Pool pool;
private Question question;
private JButton pressed;
private final int NUM_OF_ANSWERS = 4;
private Listener lis = new Listener();
//private JPanel questionPanel;
private JPanel answersPanel;
private String tf;
private Font font = new Font("Serif", Font.BOLD, 24);
private JTextField tf2 = new JTextField();
private QuestionPanel questionPanel;
public TriviaPanel() {
score = 0;
scoreString = new JTextField();
scoreString.setFont(font);
questionPanel = new QuestionPanel();
//questionPanel.setLayout(new BorderLayout());
//questionPanel.add(scoreString,BorderLayout.EAST);
this.setLayout(new GridLayout(2, 1));
pool = null;
try {
pool = new Pool();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
question = pool.getQuestion();
String[] answers = question.shuffle();
tf = question.getQuestion();
//tf2.setText(question.getQuestion());
//questionPanel.add(tf2,BorderLayout.CENTER);
this.add(questionPanel);
answersPanel = new JPanel();
answersPanel.setLayout(new GridLayout(2, 2));
buttons = new JButton[NUM_OF_ANSWERS];
for (int i = 0; i < NUM_OF_ANSWERS; i++) {
buttons[i] = new JButton(answers[i]);
answersPanel.add(buttons[i]);
buttons[i].addActionListener(lis);
}
this.add(answersPanel);
// timer.start();
scoreString.setText("Score: " + score + "/" + pool.getIterator() * CORRECT);
}
// #Override
// protected void paintComponent(Graphics g) {
// super.paintComponent(g);
// questionPanel.repaint();
// }
private void next() {
Question q = pool.getQuestion();
question = q;
tf = q.getQuestion();
String[] answers = q.shuffle();
for (int i = 0; i < NUM_OF_ANSWERS; i++) {
buttons[i].setText(answers[i]);
}
questionPanel.repaint();
}
private void gameOver() {
JOptionPane.showConfirmDialog(null,
"Score: " + score, "Select an Option...", JOptionPane.YES_NO_CANCEL_OPTION);
}
private void check(String guess) {
// timer.stop();
String answer = question.getCorrectAnswer();
if (guess.equals(answer)) {
score += CORRECT;
tf = "Correct!!!";
} else {
score -= INCORRECT;
tf = "Wrong answer";
}
questionPanel.repaint();
scoreString.setText("Score: " + score + "/" + pool.getIterator() * CORRECT);
// OH GOD THIS IS A BAD IDEA!
// try {
// TimeUnit.SECONDS.sleep(1);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
Timer timer = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Timer timer = (Timer) e.getSource();
timer.stop();
// Personally, I'd use a listener, but this will do
afterCheckDelay();
}
});
timer.start();
}
protected void afterCheckDelay() {
if (pool.getIterator() < pool.getSize()) {
//timer.restart();
next();
} else {
gameOver();
}
}
private class QuestionPanel extends JPanel {
public QuestionPanel() {
this.setLayout(new BorderLayout());
this.add(scoreString, BorderLayout.EAST);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setFont(font);
FontMetrics fm = g.getFontMetrics();
int y = ((getHeight() - fm.getHeight()) / 2) + fm.getAscent();
g.drawString(tf, 10, y);
}
}
private class Listener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
pressed = (JButton) e.getSource();
String guess = pressed.getText();
check(guess);
}
}
private class TimerListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
// timer.stop();
// score -= INCORRECT;
// scoreString.setText("Score: " + score + "/" + pool.getIterator() * CORRECT);
// repaint();
// timer.restart();
// next();
}
}
}
public static class Pool {
private ArrayList<Question> questions = new ArrayList<>();
// private Scanner input = new Scanner(new File("src/trivia.txt"));
private static int iterator = 0;
public Pool() throws FileNotFoundException {
Question question = new Question("Why am I doing this", "Because I'm awesome", "You feel for the trick", "You have no idea", "To much caffine");
questions.add(question);
// while (input.hasNext()) {
// String q = input.nextLine();
// String a = input.nextLine();
// String d1 = input.nextLine();
// String d2 = input.nextLine();
// String d3 = input.nextLine();
// Question question = new Question(q, a, d1, d2, d3);
// questions.add(question);
// }
Collections.shuffle(questions);
//System.out.println(questions);
}
public Question getQuestion() {
Question q = questions.get(iterator);
iterator++;
return q;
}
public int getSize() {
return questions.size();
}
public static int getIterator() {
return iterator;
}
}
public static class Question {
private final int NUM_OF_ANSWERS = 4;
private String question;
private String[] answers = new String[NUM_OF_ANSWERS];
private final int CORRECT_ANSWER = 0;
public Question(String qu, String an, String dm1, String dm2, String dm3) {
question = qu;
answers[0] = an;
answers[1] = dm1;
answers[2] = dm2;
answers[3] = dm3;
}
public String getCorrectAnswer() {
return answers[CORRECT_ANSWER];
}
public String getQuestion() {
return question;
}
public String[] getAnswers() {
return answers;
}
public String toString() {
String str = question;
for (int i = 0; i < 4; i++) {
str += " " + answers[i];
}
str += "\n";
return str;
}
public String[] shuffle() {
String[] shuffled = new String[NUM_OF_ANSWERS];
for (int i = 0; i < NUM_OF_ANSWERS; i++) {
shuffled[i] = answers[i];
}
Collections.shuffle(Arrays.asList(shuffled));
return shuffled;
}
}
}
The following code should read a list of students and their grades from a file, compare them to each other then display the student with the highest average
public class CSDept implements Comparable{
private String studentName;
private double java;
private double dataStructure;
private double algorithms;
private int numStudents;
public CSDept(){
}
public CSDept(String studentName,double java,double dataStructure,double algorithms){
this.studentName=studentName;
this.java=java;
this.dataStructure=dataStructure;
this.algorithms=algorithms;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public String getJava() {
return java+" ";
}
public void setJava(double java) {
this.java = java;
}
public String getDataStructure() {
return dataStructure+" ";
}
public void setDataStructure(double dataStructure) {
this.dataStructure = dataStructure;
}
public String getAlgorithms() {
return algorithms+" ";
}
public void setAlgorithms(double algorithms) {
this.algorithms = algorithms;
}
public int getNumStudents() {
return numStudents;
}
public double getAvg(){
return (java+algorithms+dataStructure)/3;
}
public int compareTo(Object student) {
if(this.getAvg()>((CSDept)student).getAvg()) return 1;
if (this.getAvg()<((CSDept)student).getAvg()) return -1;
return 0;
}
public String toString(){
return studentName+":\n"+"\t"+"Java: "+java+"\t"+"Data Structure : "+dataStructure+"\t"+"Algorithms: "+algorithms+"\n";
}}
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.TitledBorder;
public class CSDeptFrame extends JFrame{
private JPanel pnlInput=new JPanel(new GridLayout(4,2));
private JPanel pnlOutput=new JPanel(new BorderLayout());
private JPanel pnlFinal=new JPanel(new GridLayout(1,2));
private TitledBorder brdInput=new TitledBorder("Marks");
private TitledBorder brdOutput=new TitledBorder("First Student");
private JLabel lblName=new JLabel("Student Name");
private JLabel lblJava=new JLabel("Java");
private JLabel lblDataStructure=new JLabel("Data Structure");
private JLabel lblAlgorithm=new JLabel("Algorithm");
static JLabel lblFirst=new JLabel("The First Student is :");
static JTextField txtName=new JTextField(20);
static JTextField txtJava=new JTextField(20);
static JTextField txtDataStructure=new JTextField(20);
static JTextField txtAlgorithm=new JTextField(20);
static JButton btnFirst=new JButton("Who is The First Student?");
public CSDeptFrame(String title){
super(title);
pnlInput.setBorder(brdInput);
pnlInput.add(lblName);
pnlInput.add(txtName);
pnlInput.add(lblJava);
pnlInput.add(txtJava);
pnlInput.add(lblDataStructure);
pnlInput.add(txtDataStructure);
pnlInput.add(lblAlgorithm);
pnlInput.add(txtAlgorithm);
pnlOutput.setBorder(brdOutput);
pnlOutput.add(btnFirst,BorderLayout.NORTH);
pnlOutput.add(lblFirst,BorderLayout.SOUTH);
pnlFinal.add(pnlInput);
pnlFinal.add(pnlOutput);
setLayout(new BorderLayout());
add(pnlFinal);}
public static void main(String[] args){
CSDeptFrame frame=new CSDeptFrame("CS DEPT");
frame.setSize(450,200);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
final ArrayList<CSDept> cS= new ArrayList();
File readFile =new File("read.txt");
final File writeFile=new File("write.txt");
try {
Scanner scan=new Scanner(readFile);
while(scan.hasNext()){
CSDept student=new CSDept();
student.setStudentName(scan.next());
student.setJava(scan.nextDouble());
student.setDataStructure(scan.nextDouble());
student.setAlgorithms(scan.nextDouble());
cS.add(student);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, "OPS! File is not found");
}
btnFirst.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
CSDept firstStudent=new CSDept();
firstStudent.setStudentName(cS.get(0).getStudentName());
firstStudent.setJava(Double.parseDouble(cS.get(0).getJava()));
firstStudent.setDataStructure(Double.parseDouble(cS.get(0).getDataStructure()));
firstStudent.setAlgorithms(Double.parseDouble(cS.get(0).getAlgorithms()));
for (int i=0;i<cS.size();i++){
if (cS.get(i).compareTo(cS.get(i+1))==-1){
firstStudent=cS.get(i+1);
}
}
txtName.setText(firstStudent.getStudentName());
txtJava.setText(firstStudent.getJava());
txtDataStructure.setText(firstStudent.getDataStructure());
txtAlgorithm.setText(firstStudent.getAlgorithms());
lblFirst.setText("The First Student is: "+ txtName.getText());
PrintWriter out;
try {
out = new PrintWriter(new BufferedWriter(new FileWriter(writeFile,true)));
for (CSDept cs: cS){
out.println(cs.toString());
out.print("The first student is " + firstStudent.toString());
}
out.close();
} catch (IOException e1) {
e1.printStackTrace();
JOptionPane.showMessageDialog(null, "OPS! File in Not Found");
}
}
});
}}
But the problem is that the following statements don't add any objects to the arraylist, what's the problem with it?
try {
Scanner scan=new Scanner(readFile);
while(scan.hasNext()){
CSDept student=new CSDept();
student.setStudentName(scan.next());
student.setJava(scan.nextDouble());
student.setDataStructure(scan.nextDouble());
student.setAlgorithms(scan.nextDouble());
cS.add(student);
}
You problem is that you are trying to get an element at a specific index from an empty list:
final ArrayList<CSDept> cS= new ArrayList();
// ...
public void actionPerformed(ActionEvent e) {
// ...
firstStudent.setStudentName(cS.get(0).getStudentName()); // ArrayList cS is empty here
// ...
Maybe you could add a check to make sure the list is not empty before accessing the elements:
public void actionPerformed(ActionEvent e) {
if(!cS.isEmpty()) {
// do stuff
}
The reason your list is empty could be that you are reading an empty file "read.txt" so your while loop condition is never true
Scanner scan=new Scanner(readFile); // this text file is probably empty
while(scan.hasNext()){ // which makes this condition always false so loop is never executed
CSDept student=new CSDept();
student.setStudentName(scan.next());
student.setJava(scan.nextDouble());
student.setDataStructure(scan.nextDouble());
student.setAlgorithms(scan.nextDouble());
cS.add(student);
}
Furthermore, you have an ArrayIndexOutOfBoundsException risk in the for loop inside actionPerformed(). You compare current element with the next element which will, once i corresponds to the index of the last element, give an AIOBE in the comparison statement with element at index i + 1:
for (int i=0;i<cS.size();i++){
if (cS.get(i).compareTo(cS.get(i+1))==-1){ // once i = cS.size() - 1, you will get an AIOBE here
firstStudent=cS.get(i+1);
}
}
You can fix this by starting the loop at i = 1 and comparing with element at i - 1 or use a forEach loop which is a cleaner way of achieving this since it doesn't involve indexed access.
I have written save / Load methods (not sure entirely if the save works but the file 'minesweepersavestate.ser' appears in my project folder after calling saveGame()). I want to try to get the load to work because at current it doesn't seem to do anything.
Here are my functions:
public void saveGame(){
GameBoard b = new GameBoard();
try {
System.out.println("Creating File/Object output stream...");
FileOutputStream fileOut = new FileOutputStream("minesweepersavestate.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
System.out.println("Writing GameBoard Object...");
out.writeObject(b);
System.out.println("Save Successful...\n");
out.close();
fileOut.close();
} catch(FileNotFoundException e) {
System.out.println("no");
e.printStackTrace();
} catch (IOException e) {
System.out.println("no");
e.printStackTrace();
}
}
public void loadBoard()
{
GameBoard b = null;
try {
System.out.println("Creating File/Object input stream...");
FileInputStream fileIn = new FileInputStream("minesweepersavestate.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
System.out.println("Loading GameBoard Object...");
b = (GameBoard)in.readObject();
System.out.println("Load Successful...\n");
in.close();
fileIn.close();
} catch (ClassNotFoundException e) {
System.out.println("Class not found\n");
e.printStackTrace();
} catch(FileNotFoundException e) {
System.out.println("File not found\n");
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
How can I alter this method so that when i call the loadBoard() method, it brings back the game in the state it was saved?
Edit:
GameBoard Class:
public class GameBoard extends JFrame implements Serializable
{
//MENU ITEMS
private JFrame frame;
private JMenuBar menubar = new JMenuBar();
private JTable table;
//FIELDS USED FOR GAMEPLAY
private int x;
private int y;
private boolean mineTrue;
private boolean triedTrue;
private static int boardsize = 8;
private int numberOfMines = 10;
public static final int Empty = 0;
public static final int Mine = -1;
public static final int Flag = -2;
public static final int FMine = -3;
public static final int RevealedMine = -4;
public static final int RevealedEmpty = -5;
// SIZE OF BUTTONS
private int gridsize = 45;
// ARRAY FOR THE BUTTONS
private JButton[][] buttons;
private int[][] board;
//VARIABLE USED FOR LABELS
private static int noGamesPlayed = 0;
private static int noGamesWon = 0;
private int mine = 10;
private int minesLeft = 10;
private static int score = 1;
private static String playername;
// GAME STATUS
private boolean gamegoing = true;
// GAME LABELS
private JLabel space = new JLabel("");
private JTextField nameEnter = new JTextField("Enter name here: ");
private JButton saveName = new JButton("Play");
private JLabel namelabel = new JLabel("Player 1: ");
private JLabel scorelabel = new JLabel("0 points ");
private JLabel status = new JLabel("Game in Progress: ");
private JLabel gamesPlayed = new JLabel("Games Played: " + noGamesPlayed);
private JLabel gamesWon = new JLabel("Games Won : " + noGamesWon);
private JLabel noMines = new JLabel("Number of Mines: " + minesLeft);
/**
* Constructor
*/
public GameBoard() { }
/**
*Making the game Frame
*/
private void makeFrame() { }
// MAKING THE GAME MENU BAR
public void makeMenuBar(){
}
public void setx(int pmeter) { }
public void sety(int pmeter) { }
public int getx() { }
public int gety() { }
public void settried(boolean paramBoolean) { }
public boolean gettried() { }
public void setmine(boolean paramBoolean) { }
public boolean getmine() { }
//ASSIGN MINES TO RANDOM LOCATION
public void assignmines() { }
// *********************************GAME CONTROLS************
private void quit() { }
//RESETS THE BOARD
public void reset() { }
public void newGame() { }
public void biggerBoard() { }
public void changeDifficulty() { }
public void saveGame() { }
public void loadBoard() { }
// LOSING THE GAME ALERT
public void lose() { }
// WINNING THE GAME ALERT
public void win() { }
// UPDATING THE SCORE
public void updatescore() { }
public void gamesPlayed() { }
public void UpdateName() { }
public void updateGamesPlayed() { }
public void updateGamesWon() { }
//WHAT VALUES THE CHARACTER HAVE
static char whichCharacter(int value) { }
//This method shows how many mines are around the spot that was clicked
static int minesAround(int[][] board, int row, int col) { }
// This method takes in an x and y value and defines what should happen when the user clicks there.
public void click(int rows, int cols) { }
//ACTION WHEN USER CLICKS ON A BUTTON INNER CLASS
private class MouseListener extends MouseAdapter {
private int x = 0;
private int y = 0;
public MouseListener(int row, int col) { }
public void mouseClicked(MouseEvent e) { }
}
}
You need to make sure that all your fields in your class are Serializable as this tutorial suggests. Of particular note are the requirements for a class to be Serializable:
Notice that for a class to be serialized successfully, two conditions must be met:
The class must implement the java.io.Serializable interface.
All of the fields in the class must be serializable. If a field is not serializable, it must be marked transient.
This means you'll have to do some digging in the Javadocs for all the fields in your GameBoard class. For instance, I did a quick search on JFrame, and there seems to be a bit of a nuance when it comes to
saving a JFrame. When you retrieve the state of your saved game, it might be better just to recreate the GUI from scratch rather than to rely upon Serialization to do it for you. This thread also seems to concur that it's not a good idea to rely on Java to restore a GUI for you, but gives a suggestion as to how to possibly make it work:
once deserialised, you will need to show the frame with frame.setVisible(true);
I'm using the Swing library to ask a user for their zipcode, but all that is appearing is a box, without the text box, or any of the other elements that I've added in (see code). Also, you likely need to know that I'm trying to get the int AskZip() in my public static void main(String[] args) method.
private static int zip;
public static int AskZip() {
JFrame zaWindow = new JFrame("What Zipcode");
zaWindow.setSize(200, 300);
JPanel jp = new JPanel();
final JTextField tf = new JTextField("Enter Zip Here");
JLabel label = new JLabel();
JButton button = new JButton("Get Weather");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String sZip = tf.getText();
int rZip = 0;
try {
if (sZip.length() != 5) {
JOptionPane.showMessageDialog(null, "Invalid zipcode!", "Error", JOptionPane.ERROR_MESSAGE);
} else {
rZip = Integer.parseInt(sZip);
}
} catch (NumberFormatException arg) {
JOptionPane.showMessageDialog(null, "Invalid zipcode!", "Error", JOptionPane.ERROR_MESSAGE);
}
zip = rZip;
}
});
label.setText("What is your zipcode?");
jp.add(label);
jp.add(tf);
jp.add(button);
zaWindow.add(jp);
return zip;
}
JFrame zaWindow..
This should be a modal dialog or a JOptionPane. E.G. This country has 3 states, each with 10 postcodes.
import java.awt.*;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.event.ChangeListener;
class ZipQuery {
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
ZipNumberModel znm = new ZipNumberModel();
JSpinner zip = new JSpinner(znm);
JOptionPane.showMessageDialog(null, zip, "Enter Zipcode", JOptionPane.QUESTION_MESSAGE);
System.out.println("User chose " + znm.getValue());
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
}
class ZipNumberModel extends SpinnerNumberModel {
private ArrayList<Integer> zipCodes;
private int index = 0;
ZipNumberModel() {
zipCodes = new ArrayList<Integer>();
int zip = 10000;
for (int jj = 1; jj < 4; jj++) {
for (int ii = jj * zip; ii < jj * zip + 10; ii++) {
zipCodes.add(new Integer(ii));
}
}
}
#Override
public Object getValue() {
return zipCodes.get(index);
}
#Override
public Object getNextValue() {
if (index < zipCodes.size()-1) {
index++;
} else {
index = 0;
}
return zipCodes.get(index);
}
#Override
public Object getPreviousValue() {
if (index > 0) {
index--;
} else {
index = zipCodes.size()-1;
}
return zipCodes.get(index);
}
}
EDIT
I've made several corrections and am now able to compile. When attempting to add a contact to the file I receive a null pointer exception at line 13 of the ContactsCollection class:
for (int i = 0; i < contactList.size(); i++)
and line 93 of the Contacts (GUI) class:
contactList.add(contact);
Contacts class:
import java.util.*;
import java.io.*;
public class Contact implements Serializable
{
public static final long serialVersionUID = 42L;
public String name, number;
Contact()
{
name = "No name";
number = "No number";
}
Contact (String theName, String theNumber)
{
this.name = theName;
this.number = theNumber;
}
public void setName(String aName)
{
this.name = aName;
}
public void setNumber(String aNumber)
{
this.number =aNumber;
}
public String getName()
{
return name;
}
public String getNumber()
{
return number;
}
public String toString()
{
return name + ": " + number;
}
public boolean equals(Contact other)
{
if (name.equals(other.getName()) && number.equals(other.getNumber()))
{
return(true);
}
else
{
return(false);
}
}
}
Contacts Collection class
import java.io.*;
import java.util.*;
class ContactsCollection
{
public static ArrayList<Contact> contactList;
public static void write()
{
try
{
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("contactList.dat"));
for (int i = 0; i < contactList.size(); i++)
{
out.writeObject(contactList.get(i));
}
out.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
public static void read()
{
contactList = new ArrayList<Contact>();
try
{
ObjectInputStream in = new ObjectInputStream(new FileInputStream("contactList.dat"));
Contact temp;
while (in.available()!=0)
{
temp = (Contact)in.readObject();
contactList.add(temp);
}
in.close();
}
catch(FileNotFoundException e)
{
e.printStackTrace();
}
catch(IOException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
Contacts (GUI) class
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.Timer;
import java.util.*;
class Contacts extends JFrame implements ActionListener, WindowListener
{
public static final int WIDTH = 400;
public static final int HEIGHT = 600;
public static final int SMALL_WIDTH = 200;
public static final int SMALL_HEIGHT = 100;
private static final Dimension stdBtn = new Dimension(150, 50);
JPanel centerPanel, northPanel, southPanel;
ImageIcon icon;
JLabel picture;
JButton addContact, displayContacts;
JScrollPane scroll;
JTextArea textArea;
Clock clock;
Background background;
Contact contact;
ArrayList<Contact> contactList;
public Contacts()
{
super("Contacts");
this.setLayout(new BorderLayout());
this.setSize(WIDTH, HEIGHT);
this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
addWindowListener(this);
this.setLocationRelativeTo(null);
centerPanel = new JPanel();
northPanel = new JPanel();
southPanel = new JPanel();
centerPanel.setBackground(Color.BLACK);
southPanel.setBackground(Color.BLACK);
clock = new Clock();
northPanel.add(clock);
icon = new ImageIcon("ContactsBackground.jpg");
picture = new JLabel(icon);
centerPanel.add(picture);
textArea = new JTextArea("", 10, 30);
textArea.setEditable(false);
JScrollPane scroll = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
centerPanel.add(scroll);
JButton displayContacts = new JButton("Display contacts");
displayContacts.addActionListener(this);
southPanel.add(displayContacts);
JButton addContact = new JButton("Add contact");
addContact.addActionListener(this);
southPanel.add(addContact);
this.add(northPanel, BorderLayout.NORTH);
this.add(centerPanel, BorderLayout.CENTER);
this.add(southPanel, BorderLayout.SOUTH);
setResizable(false);
}
public void actionPerformed(ActionEvent e)
{
contactList = new ArrayList<Contact>();
JButton source = (JButton)e.getSource();
String contactInput = source.getText();
if (contactInput == "Display contacts")
{
ContactsCollection.read();
for (int i = 0; i < contactList.size(); i++)
{
contact = (Contact)contactList.get(i);
textArea.setText(contact.getName() + "," + contact.getNumber() + "\n");
}
}
if (contactInput == "Add contact")
{
String name = JOptionPane.showInputDialog(null, "Enter Name");
String number = JOptionPane.showInputDialog(null, "Enter Number");
contact = new Contact(name, number);
contactList.add(contact);
ContactsCollection.write();
}
}
public void windowOpened(WindowEvent e)
{}
public void windowClosing(WindowEvent e)
{
this.setVisible(false);
background = new Background();
background.setVisible(true);
}
public void windowClosed(WindowEvent e)
{}
public void windowIconified(WindowEvent e)
{}
public void windowDeiconified(WindowEvent e)
{}
public void windowActivated(WindowEvent e)
{}
public void windowDeactivated(WindowEvent e)
{}
}
Regarding
The first error I'm running into is "cannot find symbol method read()" and "cannot find symbol method write()".
You're calling a method on ArrayList, read(), that just doesn't exist. You need to call this method on one of the contents of the ArrayList, not the ArrayList itself. It's like trying to make an omelette with an egg crate -- won't work. You need to use an egg or two instead. Same thing for write().
Regarding
The second error is in the action listener for display contacts stating that "an array is required but a Contact was found".
You should tell us which line causes this error.
Edit
You show:
for (int i = 0; i < contactList.size(); i++)
{
textArea.setText(contact[i].getName() + "," + contact [i].getNumber() + "\n");
}
That code makes no sense. You need to use your list variable, contactList and get its item via the ArrayList get(...) method.
Your code suggests that you're blindly adding a bunch of code regardless of errors, and that won't work. If you can't use an IDE, you should compile often, after each 1-3 lines and fix all compilation errors before trying to add any more code. Else you'll end up with a rat's nest of errors. Also, read the manual/book. Don't guess at this stuff.