Java Serializable Saving - java

Well I have this class for a game I'm making, and I'm trying to save the ArrayList notes. When I logout, it properly print the size, for example if I have 5 notes, when I log out notes.getSize() would be 5, but when I log in, it gets reset back to nothing. Why isn't notes saving?
public class Notes implements Serializable {
private static final long serialVersionUID = -4947870743226160329L;
private ArrayList<Note> notes = new ArrayList<Note>(30);
public class Note implements Serializable {
private static final long serialVersionUID = -4589885080580317958L;
private int color = 0;
private String text = "";
public Note(int color, String text) {
this.setColor(color);
this.setText(text);
}
public void setText(String text) {
this.text = text;
}
public String getText() {
return text;
}
public void setColor(int color) {
this.color = color;
}
public int getColor() {
return color;
}
}
private transient Player player;
public Notes(Player p) {
this.player = p;
}
public void addNote(String text) {
System.out.println("Note Text: "+text);
if (text.length() > 50) {
player.getPackets().sendGameMessage("You can only enter notes up to 50 characters!");
return;
}
if (notes.size() < 30) {
notes.add(new Note(0, text));
} else {
player.getPackets().sendGameMessage("You cannot add more then 30 notes!");
return;
}
int NoteId = notes.size() - 1;
player.getPackets().sendConfig(1439, NoteId);
player.getTemporaryAttributtes().put("selectedNote", NoteId);
refreshNotes(false);
}
public void addNote(String text, int color) {
notes.add(new Note(color, text));
}
public void loadNotes() {
player.getPackets().sendIComponentSettings(34, 9, 0, 30, 2621470);
player.getPackets().sendHideIComponent(34, 3, false);
player.getPackets().sendHideIComponent(34, 44, false);
player.getPackets().sendIComponentText(34, 13, "Loading notes<br>Please wait...");
player.getPackets().sendConfig(1439, -1);
refreshNotes(true);
}
public void refreshNotes(boolean sendStartConfigs) {
for (int i = 0; i < 30; i++) {
player.getPackets().sendGlobalString(149 + i, i < notes.size() ? notes.get(i).getText() : "");
}
if (sendStartConfigs) {
for (int i = 1430; i < 1450; i++)
player.getPackets().sendConfig(i, i);
}
player.getPackets().sendConfig(1440, getFirstTotalColorValue());
player.getPackets().sendConfig(1441, getSecondTotalColorValue());
}
public int intColorValue(int color, int noteId) {
return (int) (Math.pow(4, noteId) * color);
}
public int getFirstTotalColorValue() {
int Color = 0;
for (int i = 0; i < 15; i++) {
if (notes.size() > i)
Color += intColorValue(notes.get(i).getColor(), i);
}
return Color;
}
public int getSecondTotalColorValue() {
int color = 0;
for (int i = 0; i < 15; i++) {
if (notes.size() > (i + 16))
color += intColorValue(notes.get(i + 16).getColor(), i);
}
return color;
}
public void deleteSelectedNote() {
if ((int)player.getTemporaryAttributtes().get("selectedNote") > -1) {
int slot = (int) player.getTemporaryAttributtes().get("selectedNote");
notes.remove(slot);
player.getTemporaryAttributtes().put("selectedNote", -1);
player.getPackets().sendConfig(1439, -1);
refreshNotes(false);
}
}
public void clear() {
notes.clear();
refreshNotes(false);
}
public void editNote(String string, int index) {
notes.get(index).setText(string);
refreshNotes(false);
}
public void setColor(int color, int index) {
notes.get(index).setColor(color);
refreshNotes(false);
}
public void deleteNote(int slot) {
notes.remove(slot);
refreshNotes(false);
}
public void setNotes(ArrayList<Note> setNotes) {
notes = setNotes;
refreshNotes(false);
}
}
And here is the class I manage saving/loading in
public class SerializableFilesManager {
private static final String PATH = "data/characters/";
private static final String BACKUP_PATH = "data/charactersBackup/";
public synchronized static final boolean containsPlayer(String username) {
return new File(PATH + username + ".p").exists();
}
public synchronized static Player loadPlayer(String username) {
try {
return (Player) loadSerializedFile(new File(PATH + username + ".p"));
} catch (Throwable e) {
Logger.handle(e);
}
try {
Logger.log("SerializableFilesManager", "Recovering account: "
+ username);
return (Player) loadSerializedFile(new File(BACKUP_PATH + username
+ ".p"));
} catch (Throwable e) {
Logger.handle(e);
}
return null;
}
public static boolean createBackup(String username) {
try {
Utils.copyFile(new File(PATH + username + ".p"), new File(
BACKUP_PATH + username + ".p"));
return true;
} catch (Throwable e) {
Logger.handle(e);
return false;
}
}
public synchronized static void savePlayer(Player player) {
try {
storeSerializableClass(player, new File(PATH + player.getUsername()
+ ".p"));
} catch (ConcurrentModificationException e) {
//happens because saving and logging out same time
} catch (Throwable e) {
Logger.handle(e);
}
}
public static final Object loadSerializedFile(File f) throws IOException,
ClassNotFoundException {
if (!f.exists())
return null;
ObjectInputStream in = new ObjectInputStream(new FileInputStream(f));
Object object = in.readObject();
in.close();
return object;
}
public static final void storeSerializableClass(Serializable o, File f)
throws IOException {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
out.writeObject(o);
out.close();
}
private SerializableFilesManager() {
}
}

Do NOT mark Player as transient, cause you are saving it, transient will prevent if from
getting saved, and will bring player to the default value of null, when deserialized.
Have you made the player class serializable ?
Its the Entire object graph that gets serialized or none... the purpose of transient is to make a particular member to be left off during serialization so that, the process of serialization goes smoothly.
For example, Suppose in a game we want to keep the progress of the player and hours of play for that session, but not the starting and ending times. So the starting and ending time can be made transient.

you should save your ArrayList with:
FileOutputStream fos = null;
ObjectOutputStream out = null;
try {
fos = new FileOutputStream("filename",false);
out = new ObjectOutputStream(fos);
out.writeObject(notes);
out.close();
System.out.println("Object Persisted");
} catch (IOException ex) {
ex.printStackTrace();
}
and when you open your project, import you Arraylist with:
FileInputStream fos;
try {
fos = new FileInputStream("filename");
ObjectInputStream oos = new ObjectInputStream(fos);
notes=(ArrayList) oos.readObject();
fos.close();
{
catch {
}

Thats because your Player is transient...I've tried to demonstrate your logic on other example...when Player was set to private, serialization has been successful and all data has been loaded back. Otherwise, when transient, Player reference was null, it loads only other serialized fields like int. When theres only a transient Player as field in class, the NullPointerException occurs, but ArrayList has size > 0.

Related

Update JProgressbar in JTable if JCheckbox is checked

I have problem with updating progressbar. If I check checkbox, file is automaticaly copied but progress is still 0. I use SwingWokrer, but I don't know how I can progressbar updating.
I tried many combinations, but it does not work.
This code is responsible for downloading the file from the selected row.
jTable.getModel().addTableModelListener(new TableModelListener() {
public void tableChanged(TableModelEvent e) {
int row = e.getFirstRow();
int column = e.getColumn();
TableModel tableModel = (TableModel) e.getSource();
Boolean dataObject = (Boolean) tableModel.getValueAt(row,column);
String fileNameToCopy = (String) tableModel.getValueAt(row, 0);
Long fileSize = (Long) tableModel.getValueAt(row, 1);
Float progress = (Float) tableModel.getValueAt(row, 3);
if (dataObject == true) {
customTableData.setFile(new File(fileNameToCopy));
customTableData.setFileSize(fileSize);
customTableData.setProgress(progress);;
copyFiles = new CopyFiles(customTableData);
}
}
});
CustomTableData.java
public class CustomTableData {
private File file;
private long fileSize;
private Boolean edit = false;
private float progress;
public CustomTableData() {}
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public long getFileSize() {
return fileSize;
}
public void setFileSize(long fileSize) {
this.fileSize = fileSize;
}
public Boolean isEdit() {
return edit;
}
public void setEdit(Boolean edit) {
this.edit = edit;
}
public float getProgress() {
return progress;
}
public void setProgress(float progress) {
this.progress = progress;
}
}
My CopyFiles.java class
private String fileName;
private long fileSize;
private float progress;
private CustomTableData data;
public CopyFiles(CustomTableData data) {
this.data = new CustomTableData();
this.fileName = data.getFile().getName();
this.fileSize = data.getFileSize();
this.progress = data.getProgress();
worker.execute();
}
SwingWorker<Void, Float> worker = new SwingWorker<Void, Float>(){
#Override
protected Void doInBackground() throws Exception {
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(source + fileName);
os = new FileOutputStream(destination + fileName);
byte[] buffer = new byte[BUFFER];
int length = 0;
float pro = 0;
while((length = is.read(buffer)) != -1) {
publish(pro += length);
os.write(buffer, 0, length);
}
} catch (Exception e) {
e.getMessage();
} finally {
try {
is.close();
os.close();
} catch (IOException e) {
e.getMessage();
}
}
return null;
}
protected void process(java.util.List<Float> chunks) {
for (Float f : chunks) {
progress = (f*100) / fileSize;
System.out.println("Percentage progress: " + progress + " >>> file size: " + f);
}
};
protected void done() {
System.out.println("FILE: " + fileName + " SIZE: " + fileSize);
};
};
}
And my CustomTableModel.java class
public class CustomTableModel extends AbstractTableModel {
private static final long serialVersionUID = -2929662905556163705L;
#SuppressWarnings("unused")
private File dir;
private File[] fileArray;
private List<CustomTableData> filesList;
private CustomTableData fileRow;
public CustomTableModel(File dir) {
this.dir = dir;
this.filesList = new ArrayList<CustomTableData>();
this.fileArray = dir.listFiles();
fileLoop();
}
private void fileLoop() {
for (int i = 0; i < fileArray.length; i++) {
this.fileRow = new CustomTableData();
if (fileArray[i].isFile()) {
fileRow.setFile(fileArray[i]);
fileRow.isEdit();
fileRow.getProgress();
filesList.add(fileRow);
}
}
}
private ResourceBundle resourceBundle = ResourceBundle.getBundle("MessageBundle", Locale.forLanguageTag("pl"));
protected String[] columns = new String[] {
resourceBundle.getString("fileName"),
resourceBundle.getString("fileSize") + " [byte]",
resourceBundle.getString("getFile"),
resourceBundle.getString("progress")};
#SuppressWarnings("rawtypes")
protected Class[] columnClasses = {String.class , Long.class, JCheckBox.class, JProgressBar.class};
public int getColumnCount() {
return columns.length;
}
public int getRowCount() {
return filesList.size();
}
public String getColumnName(int col) {
return columns[col].toString();
}
public Class<?> getColumnClass(int c) {
switch (c) {
case 0:
return String.class;
case 1:
return Long.class;
case 2:
return Boolean.class;
case 3:
return Float.class;
default:
return null;
}
}
public Object getValueAt(int row, int col) {
fileRow = filesList.get(row);
switch (col) {
case 0:
return fileRow.getFile().getName();
case 1:
return fileRow.getFile().length();
case 2:
return fileRow.isEdit();
case 3:
return fileRow.getProgress();
default:
return null;
}
}
public boolean isCellEditable(int row, int col) {
switch (col) {
case 0:
return false;
case 1:
return false;
case 2:
return true;
case 3:
return false;
default:
return false;
}
}
public void setValueAt(Object aValue, int row, int column) {
fileRow = filesList.get(row);
if (column == 2) {
fileRow.setEdit((Boolean)aValue);
fireTableCellUpdated(row, column);
}
}
}
This is my ProgressBarRenderer.java class
public class ProgressBarRenderer extends JProgressBar implements TableCellRenderer {
private static final long serialVersionUID = 551156559687881082L;
public ProgressBarRenderer() {
super();
}
public ProgressBarRenderer(int min, int max) {
super(min, max);
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
setValue((int) ((Float) value).floatValue());
return this;
}
}
My table view
Rozwiązanie
Progressbar jest prawidłowo aktualizowany w metodzie process()
public class CopyFiles {
private static final int BUFFER = 1024;
private int row;
private CustomTableModel customTableModel;
private String fileName;
private File file;
public CopyFiles(String fileName, CustomTableModel customTableModel, int row) {
this.fileName = fileName;
this.file = new File(PathEnum.SOURCE.getPath() + fileName);
this.customTableModel = customTableModel;
this.row = row;
worker.execute();
}
public String getFile() {
return file.getName();
}
public long getFileSize() {
return file.length();
}
public SwingWorker<Void, Float> getWorker() {
return worker;
}
SwingWorker<Void, Float> worker = new SwingWorker<Void, Float>() {
#Override
protected Void doInBackground() throws Exception {
InputStream is = null;
OutputStream os = null;
float progress = 0;
try {
is = new FileInputStream(PathEnum.SOURCE.getPath() + getFile());
os = new FileOutputStream(PathEnum.DESTINATION.getPath() + getFile());
byte[] buffer = new byte[BUFFER];
long count = 0;
int bufferLength;
while ((bufferLength = is.read(buffer)) != -1) {
count += bufferLength;
os.write(buffer, 0, bufferLength);
progress = (int) ((count * 100) / getFileSize());
publish(progress);
}
} catch (Exception e) {
e.getMessage();
} finally {
try {
is.close();
os.close();
} catch (IOException e) {
e.getMessage();
}
}
return null;
}
protected void process(List<Float> chunks) {
float currentProgress = chunks.get(chunks.size()-1);
customTableModel.setValueAt(currentProgress, row, 3);
};
protected void done() {
System.out.println("FILE: " + getFile() + " SIZE: " + getFileSize());
};
};

Strange behavior of ItemStack

For some obscene reason this works when reward = "DIAMOND" and amount = 10
public ItemStack giveReward() {
return new ItemStack(Material.matchMaterial(reward), amount);
}
p.getInventory().addItem(o.giveReward()); //gives the player 10 DIAMONDS
but when reward = "ACACIA_DOOR" and amount = 1 the same method gives the player NOTHING and no error is thrown. I have no clue why. Also
System.out.println(Material.getMaterial("ACACIA_DOOR"))
prints ACACIA_DOOR so shouldn't my above code work?
here's the rest of the code:
//imports omitted
public class ObjectivesRPG extends JavaPlugin implements Listener {
//TODO
//add view command
//implement rewards and requirements
//test for completeness
//future - allow ops to modify player data
public static void main(String args[]) {
Objective o = new Objective("Spider", 1, 3, "DIAMOND", 1);
Material m = Material.getMaterial("ACACIA_DOOR");
System.out.println(m);
//meta.setDisplayName(ChatColor.GOLD + "Excaliber");
//meta.setLore(Arrays.asList(ChatColor.AQUA + "The legendary sword", ChatColor.GREEN + "Wow"));
//sword.setItemMeta(meta);
//System.out.println(o.getName());
/*
System.out.println(Material.DIAMOND_SWORD);
ItemStack stack = new ItemStack(Material.DIAMOND_SWORD, 1);
ItemMeta meta = stack.getItemMeta();
stack.setItemMeta(meta);*/
}
private ArrayList<Objective> objectives = null;
private HashMap<String, ArrayList<Objective>> loadedPlayerData = null;
#SuppressWarnings("unchecked")
#Override
public void onEnable() {
System.out.println("ObjectivesRPG loaded");
loadedPlayerData = new HashMap<>();
File dir = getDataFolder();
if (!dir.exists()) {
Bukkit.getConsoleSender().sendMessage(ChatColor.YELLOW + "[ObjectivesRPG] Could not find data directory, creating it");
if (!dir.mkdir()) {
System.out.println("Error: Could not create data directory");
}
}
objectives = (ArrayList<Objective>) load(new File(getDataFolder(), "objectives.dat"));
if (objectives == null) {
objectives = new ArrayList<>();
}
getServer().getPluginManager().registerEvents(this, this); // ParamListener,
// ParamPlugin
}
#Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String args[]) {
if (label.equalsIgnoreCase("objectives")) {
if (sender instanceof Player) {
Player p = (Player) sender;
if(args.length == 0) {
for(Objective o: loadedPlayerData.get(p.getName())) {
p.sendMessage(o.getName() + " " + o.getTillComplete() + " ");
}
}
if (args.length > 0) {
if (args[0].equals("create")) {
if (!p.isOp()) {
p.sendMessage(ChatColor.RED + "You must be op to use this command");
} else if (args.length == 6) {
Objective objective = new Objective(args[1] ,Integer.parseInt(args[2]), Integer.parseInt(args[3]), args[4], Integer.parseInt(args[5]));
objectives.add(objective);
save(objectives, new File(getDataFolder(), "objectives.dat"));
} else {
p.sendMessage(ChatColor.RED + "Error: Bad arguments.");
}
}
}
}
}
return true;
}
public void onDisable() {
save(objectives, new File(getDataFolder(), "objectives.dat"));
}
public void save(Object o, File f) {
try {
if (!f.exists()) {
f.createNewFile();
}
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(f));
os.writeObject(o);
Bukkit.getConsoleSender().sendMessage("[ObjectivesRPG] Saved objective");
os.flush();
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public Object load(File f) {
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
Object result = ois.readObject();
ois.close();
return result;
} catch (Exception e) {
return null;
}
}
#EventHandler
private void checkKills(EntityDeathEvent e) {
Entity killed = e.getEntity();
Entity killer = e.getEntity().getKiller();
if(killer instanceof Player) {
Player p = (Player) killer;
for(Objective o: loadedPlayerData.get(p.getName())) {
if(o.isComplete()) {
continue;
}
if(!o.isComplete() && (o.getRequirement() == Requirement.kill_Spiders && killed instanceof Spider ||
o.getRequirement() == Requirement.kill_Zombies && killed instanceof Zombie) ||
o.getRequirement() == Requirement.kill_Skeletons && killed instanceof Skeleton
) {
o.setTillComplete(o.getTillComplete() - 1);
if(o.getTillComplete() == 0) {
p.sendMessage(ChatColor.GREEN + "Congragulations! You completed objective " + o.getName() + "! Here is your reward!");
p.getInventory().addItem(o.giveReward());
o.setComplete(true);
}
}
}
}
}
#EventHandler
private void onQuit(PlayerQuitEvent event) {
Player player = event.getPlayer();
File f = new File(getDataFolder(), player.getName());
save(loadedPlayerData.get(player.getName()), f);
loadedPlayerData.remove(player.getName());
}
#EventHandler
private void onJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
File f = new File(getDataFolder(), player.getName());
ArrayList<Objective> playerObjectives = null;
try {
if(!f.exists()) {
f.createNewFile();
Bukkit.getConsoleSender().sendMessage("[ObjectivesRPG] Could not find " + player.getName() + "'s objective data, creating it");
playerObjectives = new ArrayList<>();
for(Objective objective: objectives) {
playerObjectives.add(objective);
}
player.sendMessage(ChatColor.GREEN + "You have new objective(s) to complete! Type /objectives to view them.");
save(playerObjectives, f);
} else {
playerObjectives = (ArrayList<Objective>) load(f);
System.out.println(objectives.size() + " " + playerObjectives.size());
//If server objective list is larger than playerObjectives new objectives must be added to player list
if(objectives.size() > playerObjectives.size()) {
player.sendMessage(ChatColor.GREEN + "You have new objective(s) to complete! Type /objectives to view them.");
for(int i = 0; i < objectives.size(); i++) {
boolean objectiveAdded = false;
for(int j = 0; j < playerObjectives.size(); j++) {
if(objectives.get(i).getName().equals(playerObjectives.get(j).getName())) {
objectiveAdded = true;
//break;
}
}
if(!objectiveAdded) {
playerObjectives.add(objectives.get(i));
}
}
save(playerObjectives, f);
}
}
loadedPlayerData.put(player.getName(), playerObjectives);
} catch(Exception e) {
e.printStackTrace();
}
}
}
public class Objective implements Serializable {
private static final long serialVersionUID = -2018456670240873538L;
private static ArrayList<Requirement> requirements = new ArrayList<>();
private String name;
private Requirement requirement;
private String reward;
private int amount;
private int tillComplete;
private boolean complete;
public Objective(String name, int requirementIndex, int tillComplete, String reward, int amount) {
if(requirements.isEmpty()) {
requirements.add(Requirement.kill_Skeletons);
requirements.add(Requirement.kill_Spiders);
requirements.add(Requirement.kill_Zombies);
}
this.name = name;
this.requirement = requirements.get(requirementIndex);
this.tillComplete = tillComplete;
this.reward = reward;
this.amount = amount;
complete = false;
}
public ItemStack giveReward() {
return new ItemStack(Material.matchMaterial(reward), amount);
}
public String getName() {
return name;
}
public Object getRequirement() {
return requirement;
}
public static ArrayList<Requirement> getRequirements() {
return requirements;
}
public static void setRequirements(ArrayList<Requirement> requirements) {
Objective.requirements = requirements;
}
public int getTillComplete() {
return tillComplete;
}
public void setTillComplete(int tillComplete) {
this.tillComplete = tillComplete;
}
public void setName(String name) {
this.name = name;
}
public void setRequirement(Requirement requirement) {
this.requirement = requirement;
}
public void setReward(String reward) {
this.reward = reward;
}
public void setComplete(boolean complete) {
this.complete = complete;
}
public String getReward() {
return reward;
}
public boolean isComplete() {
return complete;
}
}
This has tripped people up more than once. Doors are two-component items. ACACIA_DOOR represents the top-part of the door, while ACACIA_DOOR_ITEM represents the bottom-part and also the item id. Use ACACIA_DOOR_ITEM when creating an ItemStack.
Tip: If you are unsure about an item id, launch Minecraft in creative mode and enable Advanced Tooltips by pressing F3+H. The real item id will be displayed in the tool tip as you hover over items in the creative inventory. For example, hovering over an Acacia Door would display
Acacia Door (#0430)
Use this information to lookup the appropriate Material enum in org.bukkit.Material, which in this case would be ACACIA_DOOR_ITEM.

Serialization not working in my JFrames

I'm not sure why the albums aren't being serialized when the users are.
In the admin class, when I login, the userlist is populated in the JCombobox<String> userlist everytime I restart the program.
But the JComboBox<Album> comboBoxAlbumSelect isn't populated every time I restart the program.
Not sure why. Thanks.
Relevant code:
public class Admin extends JFrame implements ActionListener {
Backend backend = new Backend();
GuiCtrl ctrl = new GuiCtrl(backend);
private JComboBox<String> userlist = new JComboBox<String>();
public Admin() {
//same as login
userlist = new JComboBox<String>(getUserList());
}
public String[] getUserList() {
String[] ret = new String[backend.getUserList().size()];
int i = 0;
for (String s : backend.getUserList()) {
System.out.println(s);
ret[i++] = s;
}
return ret;
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == logout) {
this.dispose();
new Login();
}
else if (e.getSource() == add) {
try {
if (ctrl.adduser(idNumberTF.getText(), fullNameTF.getText())) {
userlist.addItem(idNumberTF.getText());
backend.storeData();
} catch (IOException|ClassNotFoundException i) {}
}
}
}
public class MainAlbumPanelv2 extends JFrame implements ActionListener {
JButton btnCreateAlbum = new JButton("Create");
JComboBox<Album> comboBoxAlbumSelect = new JComboBox<Album>();
Backend backend = new Backend();
GuiCtrl ctrl = new GuiCtrl(backend);
User loggedInUser;
public MainAlbumPanelv2(User id) {
loggedInUser = id;
comboBoxAlbumSelect = new JComboBox<Album>(getAlbumList());
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == btnCreateAlbum) {
if (ctrl.createAlbum(loggedInUser, textFieldCreateAlbum.getText())) {
Album newAlbum = new Album(textFieldCreateAlbum.getText());
comboBoxAlbumSelect.addItem(newAlbum);
}
try {
backend.storeData();
} catch (IOException i) {}
}
}
public Album[] getAlbumList() {
Album[] ret = new Album[loggedInUser.getAlbums().size()];
int i = 0;
for (Album a : loggedInUser.getAlbums()) {
System.out.println(a);
ret[i++] = a;
}
return ret;
}
}
-
public class GuiCtrl {
User loggedInUser;
Backend backend;
public GuiCtrl(Backend backend) {
this.backend = backend;
}
public boolean adduser(String user_id, String user_name) throws IOException, ClassNotFoundException {
if (backend.addUser(new User(user_id, user_name))) {
return true;
} else {
return false;
}
}
public boolean createAlbum(User user_id, String name) {
if (user_id.getAlbum(name) != null) {
return false;
} else {
user_id.addAlbum(name);
return true;
}
}
}
-
public class Backend {
private HashMap<String, User> userList = new HashMap<>();
StringTokenizer tokenizer;
public Backend() {
try {
populateList();
} catch (ClassNotFoundException | IOException e) {
throw new RuntimeException("Cannot read file");
}
}
public boolean addUser(User newUser)
{
String userId = newUser.getID();
if (userList.containsKey(userId)) {
return false;
}
userList.put(userId, newUser);
return true;
}
public void storeData() throws IOException
{
try
{
FileOutputStream file = new FileOutputStream("users.ser");
ObjectOutputStream out = new ObjectOutputStream(file);
out.writeObject(userList);
out.close();
file.close();
}
catch (IOException i)
{
i.printStackTrace();
}
}
public void populateList() throws IOException, ClassNotFoundException
{
try
{
FileInputStream file = new FileInputStream ("users.ser");
ObjectInputStream in = new ObjectInputStream(file);
userList = (HashMap<String, User>) in.readObject();
in.close();
file.close();
}
catch (IOException i)
{
i.printStackTrace();
userList = new HashMap();
}
}
}
public class Album implements Serializable{
private String name;
private ArrayList<Photo> photoList;
public Album(String name)
{
this.name = name;
photoList = new ArrayList<Photo>();
}
}
public class User implements Serializable{
private String id;
private String fullName;
private ArrayList<Album> albumList;
public User(String id, String fullName)
{
this.id = id;
this.fullName = fullName;
albumList = new ArrayList<Album>();
}
public int addAlbum(Album newAlbum)
{
Album currAlbum;
if (newAlbum == null)
{
return 0;
}
for (int x = 0; x < albumList.size(); x++)
{
currAlbum = albumList.get(x);
if (currAlbum.getName().equals(newAlbum.getName()))
{
return 0;
}
}
albumList.add(newAlbum);
return 1;
}
public ArrayList<Album> getAlbums()
{
return albumList;
}
}

Why cant I save and load these serialized variables properly?

Ok I will try to make this clear as possible. I hope it doesn't get flagged before I get an answer.
I am trying to serialize a class for saving which works just fine. But some of the variables are not getting loaded correctly. Here is the code:
I also marked out places where the code is working and not working.
EDIT: Simplified code a bit more.
Class im saving: (Simple version of it)
public class classToSave implements Serializable {
/**
*
*/
private static final long serialVersionUID = -5184436214950145051L;
public static List<classToSave> classtosavelist = new ArrayList<classToSave>();
public static classToSave one = new OtherClass1("1", 1, 1, null, Item.1, 1);
public static classToSave two = new OtherClass1("2", 1, 2, one , Item.2, 1);
public static classToSave three = new OtherClass2("3", 1, 4, two , Item.3, 2);
public boolean done = false; < WONT LOAD/SAVE
public int lvl = 0; < WONT LOAD/SAVE
transient protected String name; < OK
protected int Xpos; < OK
protected int Ypos; < OK
public Skill parent; < OK
protected Item item; < OK
public int extra = 0; < OK (This Works..)
public classToSave(String s, int x, int y, Skill parent, Item item, int cost) {
this.name = s;
this.Xpos = x;
this.Ypos = y;
if(parent != null) {
this.Xpos += parent.Xpos;
this.Ypos += parent.Ypos;
}
this.parent = parent;
this.item = item;
add(this, s);
}
private void add(classToSave classtosave, String name) {
boolean flag = true;
for(int i = 0; i < skills.size(); i++) {
if(classtosavelist.get(i).getName().equalsIgnoreCase(name)) {
flag = false;
}
}
if(flag) {
classtosavelist.add(classtosave);
}
}
public int needPoints() {
return 1 + extra;
}
public boolean Done(int points) {
if(points >= needPoints()) {
this.done = true;
}
return this.done;
}
public int getLevel() {
return this.lvl;
}
public int MAXLevel() {
return 1;
}
public void LevelUp() {
if(this.lvl < MAXLevel()) {
this.lvl++;
}
}
public void Reset() {
this.lvl = 0;
}
public Item getRenderItem() {
return this.item;
}
public String getName() {
return this.name;
}
public Skill getParent() {
return this.parent;
}
public boolean isCompleteDone() {
return (getLevel() == MAXLevel() && done);
}
Here is the save and load:
private ClassToSave classtosave;
private void save(String savename) {
if (externalStorageWriteable) {
try {
File file = new File(ctxt.getExternalFilesDir(null), savename);
FileOutputStream fos = new FileOutputStream(file, false);
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(classtosave);
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void load(String savename) throws ClassNotFoundException, StreamCorruptedException, IOException {
if (externalStorageAvailable) {
File file = new File(ctxt.getExternalFilesDir(null), savename);
FileInputStream fis = new FileInputStream(file);
ObjectInputStream is = new ObjectInputStream(fis);
ClassToSave classtosave = (ClassToSave) is.readObject();
for (int i=0; i < classtosave.classtosavelist.size(); i++) {
classtosave.classtosavelist.get(i).Done(classtosave.classtosavelist.get(i).needPoints()); < WORKS
classtosave.classtosavelist.get(i).isCompleteDone(); < DOENST WORK
classtosave.classtosavelist.get(i).getLevel(); < DOESNT WORK
if (classtosave.classtosavelist.get(i).done == true){ <DOESNT WORK
classtosave.classtosavelist.get(i).done = true;
classtosave.classtosavelist.get(i).LevelUp();
}
}
}
is.close();
}
Sorry if brackets are out of place. This code was butchered(Renamed and modified) to make it more readable.
But basically this code is used for a "Skill tree" and what it is supposed to do is save if said skill is complete or not.
If this needs fixed let me know. I can also provide more code as needed.
Your constructor misses the boolean and the int. It should be like this :
public classToSave(boolean done, int lvl, String s, int x, int y, Skill parent, Item
item, int cost) {
this.done = done;
this.lvl = lvl;
...
}

RMS stored values are not permanently available in J2ME emulator

I have code to stored the value using RMS in J2ME. It's working fine on emulator. So, my first problem is
When i restart the emulator all the stored values are deleted.
Stored values are showing in the emulator, but not in the Mobile, in which i am testing my application.
I am using NetBeans for developing my J2ME application.
===UPDATED===
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import javax.microedition.rms.*;
public class TryNew extends MIDlet implements CommandListener, ItemCommandListener {
private RecordStore record;
private StringItem registered;
static final String REC_STORE = "SORT";
//Button existUser;
Display display = null;
private Ticker ticker;
Form form = null;
Form form1 = null;
TextField tb, tb1, tb2, tb3;
ChoiceGroup operator = null;
String str = null;
Command backCommand = new Command("Back", Command.BACK, 0);
Command loginCommand = new Command("Login", Command.OK, 2);
Command saveCommand = new Command("Save New", Command.OK, 1);
Command sendCommand = new Command("Send", Command.OK, 2);
Command selectCommand = new Command("Select", Command.OK, 0);
Command exitCommand = new Command("Exit", Command.STOP, 3);
private ValidateLogin ValidateLogin;
public TryNew() {
}
public void startApp() throws MIDletStateChangeException {
display = Display.getDisplay(this);
form = new Form("Login");
registered = new StringItem("", "Registered ?", StringItem.BUTTON);
form1 = new Form("Home");
tb = new TextField("Login Id: ", "", 10, TextField.PHONENUMBER);//TextField.PHONENUMBER
tb1 = new TextField("Password: ", "", 30, TextField.PASSWORD);
operator = new ChoiceGroup("Select Website", Choice.POPUP, new String[]{"Game", "Joke", "SMS"}, null);
form.append(tb);
form.append(tb1);
form.append(operator);
form.append(registered);
registered.setDefaultCommand(selectCommand);
registered.setItemCommandListener(this);
form.addCommand(saveCommand);
ticker = new Ticker("Welcome Screen");
form.addCommand(loginCommand);
form.addCommand(selectCommand);
form.addCommand(exitCommand);
// existUser = new StringItem(null, "Registered ?");
// form.append(existUser);
form.setCommandListener(this);
form1.addCommand(exitCommand);
form1.addCommand(sendCommand);
form1.setCommandListener(this);
form.setTicker(ticker);
display.setCurrent(form);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
void showMessage(String message, Displayable displayable) {
Alert alert = new Alert("");
alert.setTitle("Error");
alert.setString(message);
alert.setType(AlertType.ERROR);
alert.setTimeout(5000);
display.setCurrent(alert, displayable);
}
public void commandAction(Command c, Displayable d) {
if (c == exitCommand) {
destroyApp(true);
notifyDestroyed();
} else if (c == backCommand) {
display.setCurrent(form);
} else if (c == loginCommand) {
ValidateLogin = new ValidateLogin(this);
ValidateLogin.start();
ValidateLogin.validateLogin(tb.getString(), tb1.getString(), operator.getString(operator.getSelectedIndex()));
} else if (c == saveCommand) {
openRecord();
writeRecord(tb.getString(), tb1.getString(), operator.getString(operator.getSelectedIndex()));
closeRecord();
showAlert("Login Credential Saved Successfully !!");
}
}
////==============================================================================/////
/// Record Management
public void openRecord() {
try {
record = RecordStore.openRecordStore(REC_STORE, true);
} catch (Exception e) {
db(e.toString());
}
}
public void closeRecord() {
try {
record.closeRecordStore();
} catch (Exception e) {
db(e.toString());
}
}
public void deleteRecord() {
if (RecordStore.listRecordStores() != null) {
try {
RecordStore.deleteRecordStore(REC_STORE);
} catch (Exception e) {
db(e.toString());
}
}
}
public void writeRecord(String login_id, String pwd, String operator_name) {
String credential = login_id + "," + pwd + "," + operator_name;
byte[] rec = credential.getBytes();
try {
if (login_id.length() > 10 || login_id.length() < 10) {
showAlert("Please Enter valid Login Id");
} else if (pwd.length() < 1) {
showAlert("Please Password !!");
} else {
record.addRecord(rec, 0, rec.length);
}
} catch (Exception e) {
db(e.toString());
}
}
private void showAlert(String err) {
Alert a = new Alert("");
a.setString(err);
a.setTimeout(Alert.FOREVER);
display.setCurrent(a);
}
public void readRecord() {
try {
if (record.getNumRecords() > 0) {
Comparator comp = new Comparator();
RecordEnumeration re = record.enumerateRecords(null, comp, false);
while (re.hasNextElement()) {
String str = new String(re.nextRecord());
showAlert(str);
}
}
} catch (Exception e) {
db(e.toString());
}
}
private void db(String error) {
System.err.println("Exception: " + error);
}
public void commandAction(Command c, Item item) {
if (c == selectCommand && item == registered) {
openRecord();
readRecord();
closeRecord();
}
}
class Comparator implements RecordComparator {
public int compare(byte[] rec1, byte[] rec2) {
String str1 = new String(rec1);
String str2 = new String(rec2);
int result = str1.compareTo(str2);
if (result == 0) {
return RecordComparator.EQUIVALENT;
} else if (result < 0) {
return RecordComparator.PRECEDES;
} else {
return RecordComparator.FOLLOWS;
}
}
}
class ValidateLogin implements Runnable {
TryNew midlet;
private Display display;
String login_id;
String pwd;
String operator_name;
public ValidateLogin(TryNew midlet) {
this.midlet = midlet;
display = Display.getDisplay(midlet);
}
public void start() {
Thread t = new Thread(this);
t.start();
}
public void run() {
if (login_id.length() > 10 || login_id.length() < 10) {
showAlert("Please Enter valid Login Id");
} else if (pwd.length() < 1) {
showAlert("Please Password !!");
} else {
showHome();
}
}
/* This method takes input from user like text and pass
to servlet */
public void validateLogin(String login_id, String pwd, String operator_name) {
this.login_id = login_id;
this.pwd = pwd;
this.operator_name = operator_name;
}
/* Display Error On screen*/
private void showAlert(String err) {
Alert a = new Alert("");
a.setString(err);
a.setTimeout(Alert.FOREVER);
display.setCurrent(a);
}
private void showHome() {
tb2 = new TextField("To: ", "", 30, TextField.PHONENUMBER);
tb3 = new TextField("Message: ", "", 300, TextField.ANY);
form1.append(tb2);
form1.append(tb3);
form1.addCommand(loginCommand);
//display.setCurrent(tb3);
display.setCurrent(form1);
}
};
}
This is what i got, when i click the Manage Emulator
You need to fix the storage_root of your app in WTK,
Whenever you start your enulator it would refer to same storage_root, by default it creates different data files for each session

Categories