I have a class called Stats, which is responsible for keeping track of the statistics in my minesweeper game, it's also responsible for saving and loading these statistics. It also has a method called showStatsGui() which pops up a JDialog which contains labels that show the stats and also a reset button. When using the application the user clicks on the stats options from a JMenuItem and that calls the Stats method showStatsGui().
This works great the first time, however after closing the JDialog and doing the same thing again, the reset button now triggers two action events when pushed. After closing and opening again it triggers 3 action events and so on.
I'm not quite sure what's going on. I have the dialog set to dispose on close. But as there is only ever one Stats object the instance variables like the resetButton still exist. Although in the method showOptionsGui they are reinitialized. So I'm not sure how that should effect it.
So my question is. Firstly is it a bad planning to do what I've done by having a class that handles the stats and the stats gui. Also what exactly is going on with the multiple calls and how can I avoid this?
I will post the code. for the entire Stats class. It's very much work in progress and still needs a lot of tidying. I don't really expect anyone to need to read it but it's just incase.
Edit: second thoughts the code was a bit long so just got rid of the stuff that had no relevance to the problem.
Oh my goodness I think I've just figured it out. I predict that if I create a new instance of the JButtons (which i thought was doing till I just looked at my code again!) every time the showStatsGui() method is called that this problem will go away.
I'll just try that now. If i'm right I would still like to know if this is considered good coding practice; putting all the stats info and gui in one class.
When you pop up your stats, you should either create an entire new dialog every time, or you should create it once and then hide and unhide it.
I have some comments on your code. Yes, it's better to separate your data and your view. Make a separate class that keeps track of the statistics, and then let your dialog read from that class when you show it.
Also, instead of using an array for each statistic, consider making a class that holds every statistic, and then simply make one array with three of those instances, once instance per difficulty. Even better, give each of them their own field, so you don't have to use your constants. Or, make your constants into an enum, and then use a Map to map your difficulty levels against these stat instances.
Instead of making one ActionListener that handles all actions, make a separate one for each button. This is done neatly if you use anonymous classes. When you construct your frame, just do the following:
One question. What would you suggest would be a good name for the class that holds all the statistics objects? It seems like a silly question, but with both classes holding statistics I'm not sure what would be a good name to call them both.
No, you should have only one class holding statistics. The other one is a simple dialog showing the statistics. You can name the classes something like Stats for the data class, and StatDialog for the view class.
Stephan van Hulst wrote:No, you should have only one class holding statistics. The other one is a simple dialog showing the statistics. You can name the classes something like Stats for the data class, and StatDialog for the view class.
Maybe I'm misunderstanding your last post. But shoudn't there be a a class that holds the map. The map that holds the 3 Stats objects (one for each difficulty). And another class that displays the statistics, and the Stats class it'self. Thats 3 classes in all. And other classes interact with the class that has the map. If they ask for the statistics it gives them the appropriate difficulty level. Also I was going to make that class take care of saving and loading. That's how I've been rewriting it. It's a big improvment on what I had anyway. At the moment i've called the class that holds the statistics objects AllStats. Which seems like a bit of a crap name but I can't think of anything more appropriate.
Yeah, you would need 3 classes. However, I don't think it's *really* necessary to make a whole new class just to keep a map with Stats. Isn't there some general class you can stick this function in? Your main class somewhere, if you have it?
I think I have a lot to learn about design patterns. I need to read more code written by professionals to learn.
At the moment the way I have it the Stats objects needs to be passed to quite a few other objects. so it would be a big hassle if I had to pass 3 Stats objects all the time. I can't think of a way to do this without it seeming messy. So at the moment I think I will have the StatsLocator class that passes the right Stats Object depending on the diffiulty level required. I had originally had all the methods, like for example getPercentage(), in the StatsLocator class and that would then call the method with the same name in the Stats class but I realized there was no need. I could just have the one method getStats(int difficulty) that returns the required Stats object and then call the method on that object. But as you say that seems like a bit much just to have a class that does the one thing.
Program design is the hardest thing to learn because I don't know any programmers in real life to commment and I can hardly post all the classes with all the hundreds and hundeds of lines of codes in a forum. And finding examples is hard because I don't know if the code i'm looking at is considered well written or poorly written. Maybe I just have to accept somethings willl be a bit unprofessional about my code.
Consider the following skeleton. It might help you get some design ideas. This is my own design, others may disagree with me:
All these classes should go in the same package. This is the model of the program. Put GUI in a separate package.
Keep Board immutable. It's mostly accessed through the Game class, which keeps track of which fields are revealed. The reveal method is the heart of that class.
I may have forgotten some stuff, but this is just to give you an idea. I left out helper methods and transient fields used to speed up calculations. These are just the bare necessities.
First of all let me just say I do not expect you to read all of this code haha.
And also thanks I really appreciate you taking the time to help me.
Also i've not bothered with packages yet. I will do that at the end cause it makes compiling difficult as I use the command line.
My program is getting pretty big. I'm trying to copy the minesweeper application on windows 7 exactly. The minesweeper game was simple and I've had the abilties to do that kind of thing for a while now. But all the options and different frames needed has got complicated. And application has a surprising amount to it because it gives the user so much flexibility. I need so many of the objects to communicate with each other it feels like they all know about each other.
A lot of this code probably won't compile at the moment cause I'm in the middle of making drastic changes which meant breaking it. And a lot of it would be edited to make it more readable and simplify it. But this lets you get an idea of all the classes and how i'm passing objects to each other. And what classes I need.
I need to start over don't I? lol
It's just I need the JPanel class for drawing. I need the class that also handles all the application menus. And I'm not sure whether to make any of these classes the basic game class as well. And if not how to make sure the classes know about each other because they seem to all need to pass things back and fourth.
This first class is bascially the main frame which has menus and such. Which also keeps track of the window size which lets the PlayPanel class know how big to make everything. So everything can be resized at anytime.
This class started out as just being the JPanel that draws everything and takes the mouse events but now it's kind of turned into a main game class. So with this and the class above it's kind of like I have to main classes. Which seems wrong.
This is my own timer class which shortened the amount of code I needed in the PlayPanel class.
This is the Frame that pops up when the game is over. Ignore all the Thread stuff I was just trying something which I will be scrapping.
This class if for all the options in the game. It also brings up an options window. Later I plan to make lots of methods in the PlayPanel class use the Options variables.
And now for all the Stats classes that I'm currently working on.
Well, I've only quickly glanced over your code, but I can see you have a lot of model code in your view classes. You should really do some research into the MVC pattern (model, view, controller).
The skeleton code I provided above as an illustration, should provide all the basic game functionality. It will completely determine the workings of the game, regardless of whether your game is played in a window, in the command prompt, or otherwise (you could even play through some hardware). The point of the MVC pattern is that no matter what you use to display and influence the data, the basic model is separate.
Now, for an MVC pattern, all you would need for the view part, is an implementation of javax.swing.table.TableCellRenderer, or a custom JPanel. The latter is probably easier (I really hate working with JTable). All the JPanel would have to do was look at an instance of the Game class, and draw the cells accordingly.
For the controller part of the pattern, you would need an implementation of javax.swing.table.TableCellEditor if you're using a JTable, or you would need to add ActionListeners/MouseListeners to your JPanel. The listeners would simply delegate the actions to the Game class.
A note about packages. They shouldn't make compiling any more awkward. You can simply compile the class containing the main method, and all the classes that are needed to run that program will automatically be compiled as well.
Thanks again. I will start reading right away. You've been so helpful!
One more thing. Do you know of a site where I can actually see other peoples well written source code for applications? I read somewhere that the way to get good at programming is to write a lot of code and read a lot of code. My own code is by far the most complicated code I've seen, which can't be good.
I wouldn't really know. One particular site I think is awesome is Java Practices. I can also highly recommend Joshua Bloch's Effective Java.
My personal coding style is mostly a product of the above resources, as well as writing lots of code, and rewriting even more code. I look at my code, see what bothers me, and find a way that makes it easier to read for me.
I recommend making lots of mistakes. You'll learn a lot.