I have created a clone of Atari Breakout game using the ACM graphics library and just finished adding a highscore interface and functionality. The player's name and score should be displayed on the GUI window (it is successfully) and also be written to a .dat binary file.
However, when the code attempts to load the existing file I get the following error.
writing aborted; java.io.NotSerializableException: acm.graphics.GCanvasListener
I've researched this error online and it seems it can be solved by editing the class to implement Serializable. However, the class throwing this error is not one of my own but rather a class that belongs to the third-party ACM graphics library. How do I solve this?
I'm not even sure why this error is being caused in the first place since the data I'm attempting to serialize is only a name and score, I'm not trying to serialize a canvas of objects or anything like that.
Main class (called Breakout)
public class Breakout extends GraphicsProgram {
... // game variables
public void run() {
... // this if clause runs when game ends
if (brickCounter > 0) {
removeAll(); // clears screen
printGameOver(); // displays game over message
HighscoreManager hm = new HighscoreManager();
String name = getHighScoreName();
hm.addScore(name, score);
hm.displayHighscores();
}
}
... // game functionality methods
private String getHighScoreName(){
IODialog dialog = new IODialog();
String name = dialog.readLine("Enter your name: ");
return name;
}
Score class
private class Score implements Serializable {
private int score;
private String name;
public Score(String name, int score) {
this.score = score;
this.name = name;
}
public int getScore() { return score; }
public String getName() { return name; }
}
ScoreComparator class
private class ScoreComparator implements Comparator<Score> {
public int compare(Score score1, Score score2) {
int sc1 = score1.getScore();
int sc2 = score2.getScore();
if (sc1 > sc2) {
return -1;
} else if (sc1 < sc2) {
return 1;
} else {
return 0;
}
}
}
HighscoreManager class
private class HighscoreManager {
private ArrayList<Score> scores;
private static final String HIGHSCORE_FILE = ".//bin//scores.dat";
ObjectOutputStream outputStream = null;
ObjectInputStream inputStream = null;
public HighscoreManager() {
scores = new ArrayList<Score>(10);
}
public ArrayList<Score> getScores() {
loadScoreFile();
sort();
return scores;
}
private void sort() {
ScoreComparator comparator = new ScoreComparator();
Collections.sort(scores, comparator);
}
public void addScore(String name, int score) {
loadScoreFile();
scores.add(new Score(name, score));
updateScoreFile();
}
public void loadScoreFile() {
try {
inputStream = new ObjectInputStream(new FileInputStream(HIGHSCORE_FILE));
scores = (ArrayList<Score>) inputStream.readObject();
}
catch (FileNotFoundException e) {
System.out.println("[Load] File Not Found Error: " + e.getMessage());
}
catch (IOException e) {
System.out.println("[Load] Input/Output Error: " + e.getMessage());
}
catch (ClassNotFoundException e) {
throw new RuntimeException("[Load] Class Not Found Error: " + e.getMessage());
}
finally {
try {
if (outputStream != null) {
outputStream.flush();
outputStream.close();
}
} catch (IOException e) {
System.out.println("[Load] Input/Output Error: " + e.getMessage());
}
}
}
public void updateScoreFile() {
try {
outputStream = new ObjectOutputStream(new FileOutputStream(HIGHSCORE_FILE));
outputStream.writeObject(scores);
}
catch (FileNotFoundException e) {
System.out.println("[Update] File Not Found Error: " + e.getMessage());
}
catch (IOException e) {
System.out.println("[Update] Input/Output Error: " + e.getMessage());
}
finally {
try {
if (outputStream != null) {
outputStream.flush();
outputStream.close();
}
} catch (IOException e) {
System.out.println("[Update] Input/Output Error: " + e.getMessage());
}
}
}
public void displayHighscores() {
int max = 10;
ArrayList<Score> scores;
scores = getScores();
int x = scores.size();
if (x > max) {
x = max;
}
removeAll(); // clears screen
int npos = 160;
int spos = 160;
for (int i = 0; i < x; i++) {
GLabel showName = new GLabel(scores.get(i).getName(), (getWidth() / 2.0) - 100, (getHeight() / 2.0) - npos);
showName.move(-showName.getWidth() / 2, -showName.getHeight());
showName.setColor(Color.WHITE);
add(showName);
npos -= 40;
}
for (int i = 0; i < x; i++) {
GLabel showScore = new GLabel(Integer.toString(scores.get(i).getScore()), (getWidth() / 2.0) + 100, (getHeight() / 2.0) - spos);
showScore.move(-showScore.getWidth() / 2, -showScore.getHeight());
showScore.setColor(Color.WHITE);
add(showScore);
spos -= 40;
}
}
After running the application:
[Load] Input/Output Error: writing aborted; java.io.NotSerializableException: acm.graphics.GCanvasListener
[Update] Input/Output Error: acm.graphics.GCanvasListener
[Load] Input/Output Error: writing aborted; java.io.NotSerializableException: acm.graphics.GCanvasListener
Your task will be to find a hidden reference from your name and score structure to the UI components. Many GUI applications use a lot of inner classes, and this might be the missing link.
When you have a class something like this:
class MyGame {
private SomeUIWidget widget;
class TopScore implements Serializable {
String name;
int score;
...
}
...
}
There is a hidden member in TopScore that references the "enclosing instance" of MyGame, including its SomeUIWidget member. When you try to serialize a TopScore instance, all the rest gets dragged in with it.
You could simply declare TopScore as a static nested class. This means that there is no enclosing instance, and serves only to hide the TopScore class from other code. But, I would suggest just making TopScore a top-level class, in its own file, because it's likely that other objects will want to use those objects in different ways—that is, it seems like a likely candidate for part of your public API.
This is an educated guess, in the absence of any actual code. To get a better answer, reduce your code to the minimum required to demonstrate the problem, and include that in your question.
You should go to the class where the fields name and score are, and add for example public class nameclass implements Serializable. I hope it works for you.
Related
I'm trying to create a client-server program where a client sends an array with two objects inside of it to the server. The first object contains just a string. The second object is a shape that the user chooses. The user can choose between 4 different shapes.
Rectangle
Square
Triangle
Rombus
So in totale there are 5 classes. Form, Rectangle, Square, Triangle and Rombus. Each shape class inherits from a superclass called "FormaObj". After the client has sent the array to the server, the server has to understand what kind of object the client has sent(Rectangle, Square etc.) and calculate the area and perimeter of that shape.
So let's say for example that i want to send a rectangle to the server.
ClientFormeThread2 co;
FormaObj f[];
FormaObj forma;
RettangoloObjThread r;
QuadratoObjThread q;
TriangoloObjThread t;
RomboObjThread ro;
public ClientFormeForm2() {
initComponents();
co = new ClientFormeThread2();
f = new FormaObj[2];
}
private void btnRettangoloActionPerformed(java.awt.event.ActionEvent evt) {
try {
String nome = "Rettangolo";
//Creating the Obj form
FormaObj forma = new FormaObj(nome);
int base = Integer.parseInt(JOptionPane.showInputDialog("Inserire il valore della base"));
//Asking the user the insert the value of the base and the height of the rectangle
int altezza = Integer.parseInt(JOptionPane.showInputDialog("Inserire il valore dell'altezza"));
//Creating the object rectangle
RettangoloObjThread r = new RettangoloObjThread(base, altezza, nome);
f[0] = forma; //Putting the first object form inside the array
f[1] = r; //Putting the second object rectangle inside the array
co.comunicaFormaRettangolo(f); //Sending the array to the server
r = co.getRettangolo();
atxVisualizza.setText("Rettangolo" + "\n" + "Base: " + r.getLato1()+ "\n" + "Altezza: " +
r.getLato2() + "\n" + "Area: " + r.getArea() + "\n" + "Perimetro: " + r.getPerimetro());
}catch(ClassNotFoundException ex) {
Logger.getLogger(ClientFormeForm2.class.getName()).log(Level.SEVERE, null, ex);
}
That's what's inside co.comunicaFormaRettangolo(f); //Sending the array to the server
public ClientFormeThread2(){
try{
clientSocket = new Socket("localhost", 8123);
OutputStream o = clientSocket.getOutputStream();
InputStream i = clientSocket.getInputStream();
outOggetto = new ObjectOutputStream(o);
inOggetto = new ObjectInputStream(i);
System.out.println("Client Attivo");
}catch (IOException e) {
System.out.println(e.getMessage());
}
}
public void comunicaFormaRettangolo(FormaObj[] forma) throws ClassNotFoundException {
try {
f = forma;
outOggetto.writeObject(f);
outOggetto.flush();
r =(RettangoloObjThread)inOggetto.readObject();
int Area = r.getArea();
System.out.println(Area);
} catch (IOException ex) {
}
After the server receives the array, it reads what's inside of it.
public class ServerFormeThread2 extends Thread{
Socket clientDaServire;
int NClient;
FormaObj f[];
FormaObj forma;
RettangoloObjThread r;
QuadratoObjThread q;
TriangoloObjThread t;
RomboObjThread ro;
ObjectInputStream inOggetto;
ObjectOutputStream outOggetto;
public ServerFormeThread2(Socket clientDaServire, int NClient) {
this.clientDaServire = clientDaServire;
this.NClient = NClient;
}
public void run(){
try{
OutputStream os = clientDaServire.getOutputStream();
InputStream ois = clientDaServire.getInputStream();
outOggetto = new ObjectOutputStream(os);
inOggetto = new ObjectInputStream(ois);
f = (FormaObj[]) inOggetto.readObject(); //Reading the array
String NomeForma = f[0].getMessaggio(); //here i basically get the name of the shape.
while(!NomeForma.equals("Disconnetti")){
if(NomeForma.equals("Rettangolo")){ //checks whether the value of "NomeForma" equals"Rectangle"
r = (RettangoloObjThread) f[1]; //it reads the rectangle that has been stored inside the array
r.calcolaAreaRettangolo(); //here it calculates the area
r.calcolaPerimetroRettangolo(); //and here the perimeter
outOggetto.writeObject(r); //and here i only send the object rectangle back to the client because that's what i actually need
outOggetto.flush();
}
f = (FormaObj[]) inOggetto.readObject(); // i continue listening for other arrays containing
shapes that the client might send
NomeForma = f[0].getMessaggio();
}
outOggetto.writeObject(f);
outOggetto.flush();
outOggetto.close();
}catch(Exception e){
e.printStackTrace();
}
The Problem
The first time that an object is sent to the server everything works. So the client receives back the object rectangle and it displays the area and the perimeter on an TextArea. But when i try to send a second array containing another rectangle, the server doesn't read it. The whole program just freezes and i can't do anything apart from closing the server. No error appears. Down below i put the code for the classes "RettangoloObjThread" and "FormaObj"
RettangoloObjThread
import java.io.Serializable;
public class RettangoloObjThread extends FormaObj implements Serializable {
private int lato1;
private int lato2;
private int Area;
private int Perimetro;
public RettangoloObjThread(int lato1, int lato2, String nomeForma) {
super(nomeForma);
this.lato1 = lato1;
this.lato2 = lato2;
this.Area = 0;
this.Perimetro = 0;
}
public int getLato1() {
return lato1;
}
public void setLato1(int lato1) {
this.lato1 = lato1;
}
public int getLato2() {
return lato2;
}
public void setLato2(int lato2) {
this.lato2 = lato2;
}
public int getArea() {
return Area;
}
public void setArea(int Area) {
this.Area = Area;
}
public int getPerimetro() {
return Perimetro;
}
public void setPerimetro(int Perimetro) {
this.Perimetro = Perimetro;
}
public void calcolaAreaRettangolo(){
Area = lato1 * lato2;
}
public void calcolaPerimetroRettangolo(){
Perimetro = (lato1 + lato2)*2;
}
}
FormaObj
import java.io.Serializable;
public class FormaObj implements Serializable{
private String messaggio;
public FormaObj(String messaggio) {
this.messaggio = messaggio;
}
public String getMessaggio() {
return messaggio;
}
public void setMessaggio(String messaggio) {
this.messaggio = messaggio;
}
If your application is frozen, it means that the problem is in the thread deadlock, or an infinite loop is running somewhere, or something is considered very long-determined by the debugger.
It is also possible that your application simply threw an exception, but it was not logged because it was not handled properly.
You can track the problem yourself if you run the applications in debug mode and set breakpoints on the desired lines.
To format the code, use Ctrl+Alt+L
It will be more convenient this way.
Be careful with input streams, as they can only be used once.
In any case, running the app in debug mode will help you solve the problem and gain some experience.
I managed to solve the problem by adding writeUnshared() instead of the normal write()
I am trying to implement a save and load function in my program that saves an arrayList to a textfile and then can later load all of the past lists I have saved and print them out. I am currently using these two methods:
public static void save(Serializable data, String fileName) throws Exception {
try (ObjectOutputStream oos = new ObjectOutputStream((Files.newOutputStream(Paths.get(fileName))))) {
oos.writeObject(data);
}
}
public static Object load(String fileName) throws Exception {
try (ObjectInputStream oos = new ObjectInputStream((Files.newInputStream(Paths.get(fileName))))) {
return oos.readObject();
}
}
As well as a class that represents a list as serializable data.
The problem with this is that it won't save the data after I terminate the program, and when it loads data it prints it with a great deal of extra text besides the list I want it to return. Is there a better or easier way of doing this?
I once had a same problem. So I will show you how to do it ...
Be the below Level class is what is to be saved:
public class Level implements Serializable {
private int level = 1;
private int star;
private int point;
// Constructor
public Level() {
}
public void setLevel(int level) {
this.level = level;
}
public int getLevel() {
return level;
}
public void setStar(int stars) {
this.star = stars;
}
public int getStar() {
return star;
}
public void setPoint(int points) {
this.point = points;
}
public int getPoint() {
return point;
}
#Override
public String toString() {
return "Level-" + level + " " +
(star > 1 ? star + " stars": star + " star") + " " +
(point > 1 ? point + " points" : point + " point") + "\n";
}
}
We will save the list into this file:
private static final String FILENAME = "data.level";
This is the List of our objects:
List<Level> mLevels;
Call this method to save the list into the file:
private void save() {
if(mLevels.isEmpty()) {
return;
}
try
{
ObjectOutputStream oos = new ObjectOutputStream(mContext.openFileOutput(FILENAME, Context.MODE_PRIVATE));
oos.writeObject(mLevels);
}
catch (IOException e)
{
//Toast.makeText(mContext,e.getMessage(),Toast.LENGTH_SHORT).show();
}
}
Use this method to load the list from saved file. Notice, we cast the list of our object with this (List<Level>) ois.readObject(); in the method:
private void load() {
try
{
ObjectInputStream ois = new ObjectInputStream(mContext.openFileInput(FILENAME));
mLevels = (List<Level>) ois.readObject();
}
catch (IOException e)
{
//Toast.makeText(mContext,e.getMessage(),Toast.LENGTH_SHORT).show();
}
catch (ClassNotFoundException e)
{
//Toast.makeText(mContext,e.getMessage(),Toast.LENGTH_SHORT).show();
}
if(mLevels == null) {
mLevels = new ArrayList<>();
//Toast.makeText(mContext,"List created",Toast.LENGTH_SHORT).show();
}
}
By now, you should get the idea of how to save your own list.
So I am trying to create a feature where two current objects can be saved so next time they can be loaded instead of being created again. I have a problem with following class:
public class Investor implements Serializable {
private String investorName;
private double investorCapital;
private ArrayList<Share> shareOwned;
private ArrayList<Integer> numberOwned;
public Investor(String name, double capital) {
investorName = name;
investorCapital = capital;
shareOwned = new ArrayList<Share>();
numberOwned = new ArrayList<Integer>();
}
P.S. I removed function just to show structure. Then I execute following code:
File investorData = new File("inv1.ser");
if(investorData.exists()) {
try {
FileInputStream loadData = new FileInputStream(investorData);
ObjectInputStream ois = new ObjectInputStream(loadData);
inv1 = (Investor) ois.readObject();
loadData.close();
ois.close();
} catch (Exception exc) {
JOptionPane.showMessageDialog(null, "An error occurred", "Error", JOptionPane.ERROR_MESSAGE);
}
}
else {
try {
String name = JOptionPane.showInputDialog(null, "What is your name?", "Creating new investor", JOptionPane.QUESTION_MESSAGE);
double capital = Double.parseDouble(JOptionPane.showInputDialog(null, "What is your investor capital?", "Creating new investor", JOptionPane.QUESTION_MESSAGE));
inv1 = new Investor(name, capital);
}
catch(NullPointerException exc) {
JOptionPane.showMessageDialog(null, "You must enter details in order to proceed", "File Not Found", JOptionPane.ERROR_MESSAGE);
}
JOptionPane.showMessageDialog(null, "New investor " + inv1.getInvestorName() + " with balance: " + inv1.getInvestorCapital() + " has been successfully created!", "Investor Created", JOptionPane.INFORMATION_MESSAGE);
try {
FileOutputStream saveFile = new FileOutputStream(investorData);
ObjectOutputStream oos = new ObjectOutputStream(saveFile);
oos.writeObject(inv1);
saveFile.close();
oos.close();
}
catch(Exception exc) {
JOptionPane.showMessageDialog(null, "An error occurred", "Error", JOptionPane.ERROR_MESSAGE);
}
}
When I launch program first time it prompts me to create new Investor object which it does successfully and saves in appropriate location and so on. After that I can use program: buy/sell shares etc, but once I close it, and open again, it doesn't recognize shares that were bought before. So for example if when I closed I had Gold - 100, then when I open program again it will show Gold - 100 and will try to buy 10 more, it will add new Gold object to shareOwned and I will have Gold - 100, Gold - 10. So as I understand it cannot recognize old Gold object and added new one (as was intended if it never existed).
I cannot upload a whole program because it is quite big, there is buyShare method in investor class:
public void buyShare(double price, int amount, Share stock) {
investorCapital -= price * amount;
if(shareOwned.contains(stock)) {
numberOwned.add(shareOwned.indexOf(stock), numberOwned.get(shareOwned.indexOf(stock)) + amount);
}
else {
shareOwned.add(stock);
numberOwned.add(amount);
}
}
Share class(without functions):
public class Share implements Serializable {
private String shareName;
private double shareValue;
private int shareAvailable;
private final double SHARE_PURE_VALUE;
public Share(String name, double value, int available) {
shareName = name;
SHARE_PURE_VALUE = value;
shareValue = value / available;
shareValue = Math.round(shareValue * 10) / 10;
shareAvailable = available;
}
You can see where I check for "contains" it should return just add numberOwned, but instead it creates new one, so it cannot find previous Gold that was saved before. Sorry for explaining so badly, I can send a program if that will be more convenient.
If I understood your problem, you expect to have "Gold - 110", not "Gold - 100, Gold - 10", right?
So, I think you have to implement equals and hashCode methods on Share class. When "shareOwned.contains(stock)" is called, never returns true, correct?
That's why you always have a new stock object in your list.
Add commons-lang3 to your project and put this code on your Share class:
#Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
#Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
Should work.
Thank you so much! I solved the problem. As it was mentioned I had to override equals() and hashCode() methods in Share class and now everything working (seems at least) perfectly. I was trying to use loops to check names instead but this solution is much simpler!
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Share share = (Share) o;
if (!shareName.equals(share.shareName)) return false;
return true;
}
#Override
public int hashCode() {
return 1;
}
public void setMarketValue() {
shareValue = SHARE_PURE_VALUE / shareAvailable;
shareValue = Math.round(shareValue * 10) / 10;
}
I am new to Java, and learning new things everyday. English is not my mother language, I'm sorry.
So, I'm making a maze game in Java to learn while writing code.
For my maze game, the player needs to get to the exit of the maze asap. And the time he has, needs to be saved in an encrypted text file.
So I've got a package Highscores combining several classes. The code works more or less, it outputs in the console. Now what I need is that that output gets outputted on a JPanel next to my maze. I've added some extra info in the code
Here is my highscore class:
public class Highscore {
// An arraylist of the type "score" we will use to work with the scores inside the class
private ArrayList<Score> scores;
// The name of the file where the highscores will be saved
private static final String highscorefile = "Resources/scores.dat";
//Initialising an in and outputStream for working with the file
ObjectOutputStream output = null;
ObjectInputStream input = null;
public Highscore() {
//initialising the scores-arraylist
scores = new ArrayList<Score>();
}
public ArrayList<Score> getScores() {
loadScoreFile();
sort();
return scores;
}
private void sort() {
ScoreVergelijken comparator = new ScoreVergelijken();
Collections.sort(scores, comparator);
}
public void addScore(String name, int score) {
loadScoreFile();
scores.add(new Score(name, score));
updateScoreFile();
}
public void loadScoreFile() {
try {
input = new ObjectInputStream(new FileInputStream(highscorefile));
scores = (ArrayList<Score>) input.readObject();
} catch (FileNotFoundException e) {
System.out.println("[Laad] FNF Error: " + e.getMessage());
} catch (IOException e) {
System.out.println("[Laad] IO Error: " + e.getMessage());
} catch (ClassNotFoundException e) {
System.out.println("[Laad] CNF Error: " + e.getMessage());
} finally {
try {
if (output != null) {
output.flush();
output.close();
}
} catch (IOException e) {
System.out.println("[Laad] IO Error: " + e.getMessage());
}
}
}
public void updateScoreFile() {
try {
output = new ObjectOutputStream(new FileOutputStream(highscorefile));
output.writeObject(scores);
} catch (FileNotFoundException e) {
System.out.println("[Update] FNF Error: " + e.getMessage() + ",the program will try and make a new file");
} catch (IOException e) {
System.out.println("[Update] IO Error: " + e.getMessage());
} finally {
try {
if (output != null) {
output.flush();
output.close();
}
} catch (IOException e) {
System.out.println("[Update] Error: " + e.getMessage());
}
}
}
public String getHighscoreString() {
String highscoreString = "";
int max = 10;
ArrayList<Score> scores;
scores = getScores();
int i = 0;
int x = scores.size();
if (x > max) {
x = max;
}
while (i < x) {
highscoreString += (i + 1) + ".\t" + scores.get(i).getNaam() + "\t\t" + scores.get(i).getScore() + "\n";
i++;
}
return highscoreString;
}
}
Here is my Main class:
public class Main {
public static void main(String[] args) {
Highscore hm = new Highscore();
hm.addScore("Bart",240);
hm.addScore("Marge",300);
hm.addScore("Maggie",220);
hm.addScore("Homer",100);
hm.addScore("Lisa",270);
hm.addScore(LabyrinthProject.View.MainMenu.username,290);
System.out.print(hm.getHighscoreString());
} }
Score class :
public class Score implements Serializable {
private int score;
private String naam;
public Score() {
}
public int getScore() {
return score;
}
public String getNaam() {
return naam;
}
public Score(String naam, int score) {
this.score = score;
this.naam = naam;
}
}
ScoreVergelijken class (which means CompareScore)
public class ScoreVergelijken implements Comparator<Score> {
public int compare(Score score1, Score score2) {
int sc1 = score1.getScore();
int sc2 = score2.getScore();
if (sc1 > sc2){
return -1; // -1 means first score is bigger then second score
}else if (sc1 < sc2){
return +1; // +1 means that score is lower
}else{
return 0; // 0 means score is equal
}
} }
If anyone could explain to me what to use, it would be greatly appreciated! Thank you very much!
Also, how to use those highscores and store them encrypted in a text file. How can I achieve that?
Sincerely, A beginner java student.
to keep your data encrypted in a file, you can use CipherIn/OutputStream, just like this
public static void main(String[] args) throws Exception {
// got this example from http://www.java2s.com/Tutorial/Java/0490__Security/UsingCipherInputStream.htm
write();
read();
}
public static void write() throws Exception {
KeyGenerator kg = KeyGenerator.getInstance("DES");
kg.init(new SecureRandom());
SecretKey key = kg.generateKey();
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
Class spec = Class.forName("javax.crypto.spec.DESKeySpec");
DESKeySpec ks = (DESKeySpec) skf.getKeySpec(key, spec);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("keyfile"));
oos.writeObject(ks.getKey());
Cipher c = Cipher.getInstance("DES/CFB8/NoPadding");
c.init(Cipher.ENCRYPT_MODE, key);
CipherOutputStream cos = new CipherOutputStream(new FileOutputStream("ciphertext"), c);
PrintWriter pw = new PrintWriter(new OutputStreamWriter(cos));
pw.println("Stand and unfold yourself");
pw.flush();
pw.close();
oos.writeObject(c.getIV());
oos.close();
}
public static void read() throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("keyfile"));
DESKeySpec ks = new DESKeySpec((byte[]) ois.readObject());
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
SecretKey key = skf.generateSecret(ks);
Cipher c = Cipher.getInstance("DES/CFB8/NoPadding");
c.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec((byte[]) ois.readObject()));
CipherInputStream cis = new CipherInputStream(new FileInputStream("ciphertext"), c);
BufferedReader br = new BufferedReader(new InputStreamReader(cis));
System.out.println(br.readLine());
}
Basically you asked two questions and Leo answered your second question.
Your first question is...
what I need is that ...[the high scores]... gets outputted on a JPanel next to my maze
You didn't post any GUI code, but a subclass of JTextComponent would be more appropriate than a JPanel. Simply add a component, for example JTextArea and call its setText() method with your high score string as the method argument.
I have made a simple program with :
working with files(read write)
end class extends
but the program does not work. Netbeans show no errors but when i run it ......some kind of errors show up .....and well i can't understand where is my bug (i think is a logical one).
Here is the simple program:
package detyre_kursi;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
public class Detyre_kursi {
public static void main(String[] args) {
LlogariBankare llogaria1 = new LlogariBankare("aaa", 1000);
llogaria1.Balanca();
}
}
class LlogariBankare {
//variablat e instances
private String id;
private int nrLlogarise;
private int vitiHapjes;
private double balanca;
static int nrTranasksioneve = 0;
public LlogariBankare() {
System.out.println("Ju keni harruar te vendosi id dhe nrLlogarise");
}
public LlogariBankare(String id, int nrLlogarise) {
this.id = id;
this.nrLlogarise = nrLlogarise;
vitiHapjes = 0;
balanca = 0;
Lexim(this.id, this.nrLlogarise);
}
public double getBalanca() {
return balanca;
}
public int getVitiHapjes() {
return vitiHapjes;
}
private void Lexim(String s, int llog) {
try {
File file = new File("c:\\java\\balanca.txt");
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
if (scanner.next().equals(s) && scanner.nextInt() == llog) {
vitiHapjes = scanner.nextInt();
balanca = scanner.nextDouble();
}
}
} catch (IOException e) {
e.getMessage();
}
}
void Balanca() {
try{
File file = new File("c:\\java\\test.txt");
PrintWriter out = new PrintWriter(file);
out.println(this.balanca);
} catch (IOException e) {
e.getMessage();
}
System.out.println(this.id + " , ju keni " + this.balanca +
" lek ne llogarine tuaj te krijuar ne vitin " + vitiHapjes +
" dhe keni kryer " + nrTranasksioneve + " transaksione gjithsej");
}
void Terheqe(double terheqe) {
this.balanca -= terheqe;
System.out.println("Ju sapo keni terhequr " + terheqe + " nga llogaria juaj");
nrTranasksioneve++;
}
void Depozitim(double depozitim) {
this.balanca += depozitim;
System.out.println("Ju sapo keni depozituar " + depozitim + " nga llogaria juaj");
nrTranasksioneve++;
}
}
class Interesi extends LlogariBankare {
int vitiTanishem = 2012;
double interesi = 0;
int diferencaViteve = vitiTanishem - getVitiHapjes();
Interesi(String id, int nrLlogarise) {
super(id,nrLlogarise);
}
void gjejInteresisn() {
interesi = getBalanca() + getBalanca() * diferencaViteve * 0.01;
}
}
The file balanca has this line in it :
aaa 1000 1990 34000
In poor words this is some simple version of a bank.
You read the balance from a file, and
you use the Terheqe() and Depozitim() for - and + the balance.
You use Balance() to see how many $ you have. When I run it, this error show up:
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:907)
at java.util.Scanner.next(Scanner.java:1416)
at detyre_kursi.LlogariBankare.Lexim(Detyre_kursi.java:57)
at detyre_kursi.LlogariBankare.<init>(Detyre_kursi.java:40)
at detyre_kursi.Detyre_kursi.main(Detyre_kursi.java:11)
Java Result: 1
This line causing issue. scanner.nextInt() might not be an int and I feel it is not good to do two next() calls unless you have specific reason.
if(scanner.next().equals(s)&&scanner.nextInt()==llog){
It's just a wild guess, but try replacing:
scanner.next().equals(s)
with:
s.equals(scanner.next())
I think your logical problem is from the constructor of
LlogariBankare llogaria1 = new LlogariBankare("aaa", 1000);
Check it out again.