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);
Related
This question already has answers here:
adding components dynamically in a JPanel
(2 answers)
Closed 5 years ago.
I am working on a school project and i am stuck. I am trying to create a panel (simple add methon on JFrame) in a listener after JMenuItem is clicked, but it doesn't work. If i try to create the panel outside the listener, it works just fine bud inside no. Panel is just extended JPanel, for now with nothing but in a future a plan to add there some features.
public class Gui implements GuiConstants, ActionListener {
public static final int INIT_WIDTH = 1024;
public static final int INIT_HEIGHT = 560;
private JFrame frame;
private KPanel KPanels[];
private GridBagConstraints gbc;
public Gui() {
KPanels = new KPanel[4];
this.gbc = new GridBagConstraints();
}
/**
* Vytváří okno aplikace + inicializuje toolbar
*/
public void createWindow() {
frame = new JFrame(Strings.get("window-title"));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle(Strings.get("window-title"));
frame.setJMenuBar(new KToolbar());
frame.pack();
frame.setSize(Gui.INIT_WIDTH, Gui.INIT_HEIGHT);
frame.setVisible(true);
frame.setLayout(new GridBagLayout());
addToolbarListener(this);
createPanel(1);
}
/**
* Nastaví listener pro toolbar akce (kliknutí)
* #param listener
*/
public void addToolbarListener(ActionListener listener) {
((KToolbar) frame.getJMenuBar()).addActionListener(listener);
}
public void disableToolbarItem(int itemId) {
((KToolbar) frame.getJMenuBar()).disable(itemId);
}
public KPanel createPanel(int i) {
return this.createPanel(i, null);
}
/**
* Vytvoří i-tý panel v případě, že ještě neexistuje a i je v rozsahu 0-3 včetně
* #param i
* #return
*/
public KPanel createPanel(int i, Color color){
if (i > 3 || i < 0 || KPanels[i] != null) {
return null;
}
this.KPanels[i] = new KPanel();
if (color != null)
this.KPanels[i].setBackground(color);
this.gbc.fill = GridBagConstraints.BOTH;
this.gbc.weightx = 1;
this.gbc.weighty = 1;
this.gbc.gridx = i % 2;
this.gbc.gridy = i / 2;
this.frame.add(this.KPanels[i], this.gbc);
return this.KPanels[i];
}
/**
* Odstraní t-tý panel v případě, že existuje a i je v rozsahu 0-3 včetně.
* #param i
* #return
*/
public boolean removePanel(int i) {
if (i > 3 || i < 0 || KPanels[i] == null) {
return false;
}
this.frame.remove(this.KPanels[i]);
this.KPanels[i] = null;
return true;
}
#Override
public void actionPerformed(ActionEvent e) {
createPanel(2, Color.CYAN);
}
}
public class KMenuItem extends JMenuItem {
private int id;
KMenuItem(String name, int id) {
super(name);
this.id = id;
}
public int getId() {
return id;
}
}
public class KToolbar extends JMenuBar{
ArrayList<KMenuItem> KMenuItems;
KToolbar() {
super();
KMenuItems = new ArrayList<>();
generateMenu();
}
public void addActionListener(ActionListener listener) {
for (KMenuItem item : KMenuItems) {
item.addActionListener(listener);
}
}
public void disable(int id) {
for (KMenuItem mi : KMenuItems) {
if (mi.getId() == id)
mi.setEnabled(false);
}
}
public void enable(int id) {
for (KMenuItem mi : KMenuItems) {
if (mi.getId() == id)
mi.setEnabled(true);
}
}
private KMenuItem getLast() {
return KMenuItems.get(KMenuItems.size() - 1);
}
private void generateMenu() {
JMenu game = new JMenu(Strings.get("game"));
KMenuItems.add(new KMenuItem(Strings.get("button-exit"), Gui.EXIT));
game.add(getLast());
JMenu newGame = new JMenu(Strings.get("button-new-game"));
KMenuItems.add(new KMenuItem(Strings.get("button-new-game-current"), Gui.NEW_GAME_CURRENT));
newGame.add(getLast());
KMenuItems.add(new KMenuItem(Strings.get("button-new-game-panel"), Gui.NEW_GAME_PANEL));
newGame.add(getLast());
game.add(newGame);
KMenuItems.add(new KMenuItem(Strings.get("button-save"), Gui.SAVE));
game.add(getLast());
KMenuItems.add(new KMenuItem(Strings.get("button-load"), Gui.LOAD));
game.add(getLast());
KMenuItems.add(new KMenuItem(Strings.get("button-abort-game"), Gui.ABORT_GAME));
game.add(getLast());
add(game);
}
}
public class KPanel extends JPanel {
}
public interface GuiConstants {
// System
public static final int EXIT = 1;
public static final int SAVE = 2;
public static final int LOAD = 3;
// Language
public static final int CHANGE_LANG = 4;
// Game
public static final int NEW_GAME_PANEL = 5;
public static final int NEW_GAME_CURRENT = 6;
public static final int UNDO_GAME = 7;
public static final int REDO_GAME = 8;
public static final int ABORT_GAME = 9;
public static final int HINT_GAME = 10;
}
public class Main {
private Gui GUI;
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Main();
}
});
}
Main() {
GUI = new Gui();
GUI.createWindow();
}
}
Edit: added complete example. There is no error log. I even checked object references and it all fits. It just doesn't add to the frame somehow a i dont know why.
I solved it on my own. I forgot to call frame.revalidate() with each frame.add (in the createPanel method).
I have form that button can auto re-size their size when mouse hover on button and default their size when mouse is exited. It work normally first time but after i try it more than one time their size is enlarged that i can not control normally.
ImageIcon ima=new ImageIcon("C:\\Users\\chen rina\\Pictures\\win.png");
ImageIcon icon;
Thread thr;
Runnable r=new Runnable() {
#Override
public void run() {
int i=40;
while(i!=80){
try{
Thread.sleep(20);
Image scale=ima.getImage().getScaledInstance(i,i,Image.SCALE_FAST);
icon=new ImageIcon(scale);
btn2.setIcon(icon);
i=i+5;
}
catch(Exception ex){}
}
}
};
private void btn2MouseEntered(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
thr=new Thread(r);
thr.start();
}
Runnable res=new Runnable() {
int i;
#Override
public void run() {
int i=80;
while(i!=40){
try{
Thread.sleep(20);
Image scale=ima.getImage().getScaledInstance(i,i,Image.SCALE_AREA_AVERAGING);
icon=new ImageIcon(scale);
btn2.setIcon(icon);
i=i-5;
}
catch(Exception ex){}
}
}
};
private void btn2MouseExited(java.awt.event.MouseEvent evt) {
thr=new Thread(res);
thr.start();
}
Your code violates Swing thread integrity rules by making Swing calls, here setIcon(...) from within a background state. Having said that, why not simplify all of this by:
Reading in and creating and storing your ImageIcons once and only once
Never ignore exceptions as you're doing. That's unsafe coding.
Most important, use a Swing Timer to simply swap icons every 20 msec, and have no fear about violating Swing threading rules.
Your grow Timer's ActionListener could be as simple as this:
// a private inner class
private class GrowListener implements ActionListener {
private int index = 0;
#Override
public void actionPerformed(ActionEvent e) {
// assuming the button is called button and the list iconList
button.setIcon(iconList.get(index));
index++;
if (index >= iconList.size()) {
((Timer) e.getSource()).stop();
}
}
}
The iconList would look something like:
private List<Icon> iconList = new ArrayList<>();
And you could fill it with code looking something like:
for (int i = startLength; i <= endLength; i += step) {
Image img = originalImg.getScaledInstance(i, i, Image.SCALE_FAST);
iconList.add(new ImageIcon(img));
}
And a more complete and runnable example:
import java.awt.Dimension;
import java.awt.Image;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.*;
#SuppressWarnings("serial")
public class ResizeIconTest extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
private static final int START_LENGTH = 40;
private static final int END_LENGTH = 120;
private static final int STEP = 5;
private static final int TIMER_DELAY = 20;
private static final String URL_SPEC = "https://upload.wikimedia.org/wikipedia/commons/"
+ "thumb/2/2b/Oryx_gazella_-_Etosha_2014_square_crop.jpg/"
+ "600px-Oryx_gazella_-_Etosha_2014_square_crop.jpg";
private JButton button = new JButton();
private ResizeIcon resizeIcon;
public ResizeIconTest() throws IOException {
add(button);
URL imageUrl = new URL(URL_SPEC);
BufferedImage originalImg = ImageIO.read(imageUrl);
resizeIcon = new ResizeIcon(button, originalImg, START_LENGTH,
END_LENGTH, STEP, TIMER_DELAY);
button.setIcon(resizeIcon.getSmallestIcon());
button.addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
resizeIcon.grow();
}
#Override
public void mouseExited(MouseEvent e) {
resizeIcon.shrink();
}
});
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
ResizeIconTest mainPanel = null;
try {
mainPanel = new ResizeIconTest();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
JFrame frame = new JFrame("ResizeIconTest");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class ResizeIcon {
private List<Icon> iconList = new ArrayList<>();
private AbstractButton button;
private int delayTime;
private Timer growTimer;
private Timer shrinkTimer;
public ResizeIcon(AbstractButton button, BufferedImage originalImg,
int startLength, int endLength, int step, int delayTime) {
this.button = button;
this.delayTime = delayTime;
for (int i = startLength; i <= endLength; i += step) {
Image img = originalImg.getScaledInstance(i, i, Image.SCALE_FAST);
iconList.add(new ImageIcon(img));
}
}
public Icon getSmallestIcon() {
return iconList.get(0);
}
public void grow() {
if (growTimer != null && growTimer.isRunning()) {
return; // let's not run this multiple times
}
if (button.getIcon() == iconList.get(iconList.size() - 1)) {
return; // don't run if already at largest size
}
growTimer = new Timer(delayTime, new GrowListener());
growTimer.start();
}
public void shrink() {
if (shrinkTimer != null && shrinkTimer.isRunning()) {
return; // let's not run this multiple times
}
if (button.getIcon() == iconList.get(0)) {
return; // don't run if already at smallest size
}
shrinkTimer = new Timer(delayTime, new ShrinkListener());
shrinkTimer.start();
}
private class GrowListener implements ActionListener {
private int index = 0;
#Override
public void actionPerformed(ActionEvent e) {
button.setIcon(iconList.get(index));
index++;
if (index >= iconList.size()) {
((Timer) e.getSource()).stop();
}
}
}
private class ShrinkListener implements ActionListener {
private int index = iconList.size() - 1;
#Override
public void actionPerformed(ActionEvent e) {
button.setIcon(iconList.get(index));
index--;
if (index < 0) {
((Timer) e.getSource()).stop();
}
}
}
}
I have a Java GUI code that uses multiple JLabels within a JPanel. Each individual JLabel has a unique mouse listener that is called when the JLabel is clicked. For some reason, when one JLabel is clicked, they are all being called.
Here are the JLabels:
car1 = new JLabel(card1); //card1 is just an image icon, no problems there
car2 = new JLabel(card2);
car3 = new JLabel(card3);
Mouse Listeners:
car1.addMouseListener(new CardGUI("/cards/aceclubsS.gif", car1)); //Sends the path of the new card to be implemented as a JLabel as well as the current JLabel clicked.
car2.addMouseListener(new CardGUI("/cards/aceheartsS.gif", car2));
car3.addMouseListener(new CardGUI("/cards/acespadesS.gif", car3));
CardGUI Class:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CardGUI extends JFrame implements MouseListener
{
// instance variables - replace the example below with your own
private static JLabel called;
private static JLabel current;
private static String tmp;
private static JLabel temp;
/**
* Constructor for objects of class CardGUI
*/
public CardGUI(String path, JLabel cur)
{
temp = cur;
tmp = path;
}
public void mouseExited(MouseEvent e)
{
current = null;
called = null;
}
public void mouseEntered(MouseEvent e)
{
current = null;
called = null;
}
public void mousePressed(MouseEvent e)
{
current = null;
called = null;
}
public void mouseReleased(MouseEvent e)
{
current = null;
called = null;
}
public void mouseClicked(MouseEvent e)
{
ImageIcon ic = GameGUI.createImageIcon(tmp, "");
called = new JLabel(ic);
current = temp;
GameGUI.replace(current, called);
}
public static JLabel getCalled()
{
return called;
}
public static JLabel getCurrent()
{
return current;
}
}
The replace method in the original class:
public static void replace(JLabel jl1, JLabel jl2)
{
JLabel calledr = jl2;
p2.remove(jl1);
p2.add(calledr);
p2.revalidate();
p2.repaint();
} //p2 is the panel all of the JLabels are in
Thanks in advance!
Your CardGUI Class uses only static Variables.
static variables only exists one time for all instatnces of the class.
So
CardGUI one=new CardGUI("Path", label1)
CardGUI two=new CardGUI("otherPath", label2)
one and two share the same tmp, temp, called, current variables. So in line 2 you are overwriting the label1 in line 1.
depending on your display,refreshment, the symbols you are displaying, or the paths are also the same among all Listeners.
greets
reineke
EDIT:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CardGUI extends JFrame implements MouseListener
{
// instance variables - replace the example below with your own
private JLabel called;
private JLabel current;
private String tmp;
private JLabel temp;
/**
* Constructor for objects of class CardGUI
*/
public CardGUI(String path, JLabel cur)
{
temp = cur;
tmp = path;
}
public void mouseExited(MouseEvent e)
{
current = null;
called = null;
}
public void mouseEntered(MouseEvent e)
{
current = null;
called = null;
}
public void mousePressed(MouseEvent e)
{
current = null;
called = null;
}
public void mouseReleased(MouseEvent e)
{
current = null;
called = null;
}
public void mouseClicked(MouseEvent e)
{
ImageIcon ic = GameGUI.createImageIcon(tmp, "");
called = new JLabel(ic);
current = temp;
GameGUI.replace(current, called);
}
public static JLabel getCalled()
{
return called;
}
public static JLabel getCurrent()
{
return current;
}
}
this should work fine
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.
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.