When I first started learning java GUI (swing) programming the way I was shown was more of an MVC model which involved using interfaces to call things and pass variables across classes.
I recently started programming in a more static way, having a Jframe call its static Jpanel's and using static methods to change components. Bascially i program everything statically so I can call them from the different classes with ease.
Heres an example:
My main JFrame class called "Home", I initialise the Toolbar class statically:
private static Toolbar toolbar = new Toolbar();
Now whenever I want to do something e.g. change the colour I just call from another class:
Home.toolbar.setForeground(Color.green);
Is this an ok way of programming? So far i've not run into any troubles but I was caught out by the fact that the people I learnt from didn't do this when it seems so much easier to do.
Are there any big down sides to this way of programming?
What are the alternatives?
Basically, you should ask yourself:
"Should toolbar be associated with each object I create? Or should it be one for all objects, and once I change it, it changes for all objects?"
If you answer yourself "Yes", then it's OK, otherwise it shouldn't be static.
Of course there are many things to consider beside that.. For example, static resources are not thread-safe.
If it works, then great... It's correct.
However, I make it my goal to write code that's both maintainable and testable. The problem with static instances is that it creates strong coupling throughout the entire project. Moreover, trying to isolate a class is impossible because the static dependency cannot be mocked or injected.
Typically, GUI code cannot be unit tested. MVC, however, ensures that the testable code is separated from the GUI code.
Related
I am trying to make my first 2D game in Java, and I am stuck at the very last thing.
I have already done all the logic in game, and so do I have a class named World which holds all the information about the world, makes turns.
The problem occurs when I am trying to implement some methods to show world in GUI - by that I mean: I have my parent class: World, and then I have child classes WorldGraphic, where i want to show a beautiful world, with images etc, and WorldStrategy where it is mentioned to show only the most important aspects(not so beautiful but much more 'clear' i would say), and I would like them to be swapped in UI.
And i have decided to choose Java Swing library to do it, but I have came across a big problem - I cannot inherit both World and JFrame(which was neccessary to do GUI in my swing guide), Is there any way to omit it?
My best idea so far was to make public function in my world that would output the data to print, but I have doubts about it effectiveness, I would like to keep it private(protected), and do it somehow on inheritance basis, as my GUI will also have some other options(probably I would have to make a lot public methods)
My question is more about how should the structure of my document look like(so the code is probably useless). As i have already mentioned I am fairly new to Java and I am not sure if it is correct to suddenly make every method public just so ONE of my classes(the GUI actually) could use them.
You have several questions in your one question, which is not fully allowed here, but regardless, let me try to approach the main ones
First of all, regarding the need to extend JFrame: This is absolutely not necessary and in fact, is usually not recommended. Much better is for you to use JFrames (and other GUI component) where needed, but not extend them unless necessary. Extend the component if you are extending its underlying behaviors, in other words if you're overriding a method such as a JPanel's protected void paintComponent(Graphics g) method.
Should WorldGraphic and WorldStrategy both extend World? I'm not sure that this is needed or desired. It sounds as if you're trying to separate your program's GUI portion, its "view", from its logic, the "model", and if so, both aspects do not need to and probably shouldn't extend from a parent class, but rather should be connected by a controller class.
Regarding, "As i have already mentioned I am fairly new to Java and I am not sure if it is correct to suddenly make every method public just so ONE of my classes(the GUI actually) could use them.": only make a method public if it is to be called by an outside class.
Of course, for a more detailed and concrete answer, you'll probably want to post your relevant minimal reproducible example code.
I'm new to creating my own software. I'm a student so I've created things that have been layed out step by step but I've never really done the process myself.
I've been trying to implement good design techniques and make good use of OOP but I'm worried that the code I have isn't very well written.
My main worry is the main method. Where I'm making a chat program I created a class ChatClient to house the main method. But I've found that all the code I really need to put in the main method is a call to a JFrame class telling it to show the program's interface. From here the entire functionality of the program is handled in other classes.
Should I be pulling more control of the way the program runs into the main method? Or is it actually fine to have a single line for a main method?
The main method and its surrounding class should ideally be used only as an entry point to start the program.
Each class you develop should be separate and have their own responsabilities since in the future they could actually be usefull on other programs/projects. You should always aim for a project with low coupling and high cohesion (more on this matter here: https://stackoverflow.com/a/14000957/6341202).
So, getting back to your original question, having only a line of code in the main method to initialize your JFrame is totally fine!
In the main method the good practice is to call to other method that is who is going to execute the program.
public static void main(String[] args){
Classname program = new Classname();
program.start();
}
public program(){
//The code that you want in the main
}
Instead of stuffing all the code in main() method its better if you write the code in a manner where it is loosely coupled and necessary modifications to the existing code are possible ie. maintainability
Having single line of code in the main method is good enuough as long as you have written your work flow in other classes and methods using good OOPs concepts.
The main method is the only method to which you cannot assign a meaningful name. Therefore it should not do anything unexpected.
Ideally it contains only one function call. Exception handling and some logging (program version, build date) should also be fine. But not more.
I know it's not efficient, but I don't really know why.
Most of the time, when you implement your game you got a main class which has a loop and updates every frame and creates certain objects.
My question is why it's not considered efficient to pass the main class to every object in its constructor?
In my case, I developed my game in Java for Android, using LibGDX.
Thank you!
It increases coupling (how much objects depend on each other) and therefore reduces re-usability and has the tenancy to produce 'spaghetti code'. I don't really understand what you mean by not being 'efficient', but this is why you shouldn't do it.
You should also consider why you need that main class in every single object. If you really think you do, you might need to reconsider your system design. Would you mind elaborating on why you think you need it?
Mostly, it is a matter of coupling the code and making proper design decisions.
You should avoid dependencies between classes whenever possible. It makes the code easily maintainable and the whole design clearer.
Consider the case: you are creating a simulation racing game. You have a few classes for such entities: wheel, engine, gearshift knob, etc... and non-entities: level, player...
Let's say, you have some main point (i.e. GameEngine class where you create instances).
According to you're approach you want to pass GameEngine's instance in entities constructors (or related mutator methods). It's not the best idea.
You really want to allow wheels or breaks to have the knowledge about the rest of the world (such as player's informations, scores, level etc.) and give them access to it's public interface methods?
All classes should have at small level of responsibility (and knowledge about other items) as possible.
If you really need reference to some kind of main point object in you're classes consider using dependency injection tools, such as Dagger.
It won't make you're game design better, but, at least, forces you to favor composition over inheritance - what leads to create better code.
It's not entirely inefficient, since (afiak in the general case) passing a reference to a method is quite cheap when you consider the number of JVM opcodes required, however, a possibly more efficient way of doing this would be to make a static instance of the game class and access that static field from the other classes. You would have to test these two options yourself.
In addition, passing a reference to the methods could make maintaining the code harder, as you have ultimately added a dependency.
I have a project called Visual Data Structures. I have a OOP design like this.
Class VisualDataStructures extends JFrame
Class ControlPanel extends JPanel
Class CodePanel extends JPanel
The Class VisualDataStructures has the main. This class has an instances of Class ControlPanel and CodePanel.
The Class ControlPanel has JMenuItem named "Load" inside a JMenuBar.
The Class CodePanel has a JTextArea.
Question:
I need to have a actionlistener for the JMenuItem named "load" inside the class ControlPanel. When the load is clicked, the user will enter the directory of the file, then the file will be loaded and displayed at the JTextArea of the CodePanel.
Do i need to pass the object CodePanel which is instantiated from the VisualDataStructures to the ControlPanel in order for me to use the object and then modify the value of the JTextArea?
Does anybody know a better approach for this? Thanks.
It's a bit difficult to answer that question without seeing the actual code, but I will still try. Maybe if you could share your code somehow, via Github, Bitbucket, as a Gist or in a Pastebin, I could give a better answer. It then might also be better to do that on CodeReview stackexchange instead of StackOverflow.
In general, I find it a bit suspicious that there are so many extends from GUI parent classes. Usage by extension can be a bit of an anti-pattern. It might lead to seemingly simple code in tiny applications in the first place, but in the long run it tends to obfuscate source code because it encourages a mix of business logic and UI. It's a misunderstanding that extension is the core of OOP. It's not. Polymorphic abstraction in order to decouple and invert key dependencies, that's the core of OOP. Extension is just a nice and convenient goody on top of that, and it's overused.
Speaking of that, you might have heard of MVC - Model View Controller. This is the typical pattern for UIs to keep things separate.
You do not want the ActionListener that reacts on the load action to directly know the CodePanel, for a dependency like that this is too concrete. You want to have an abstraction in-between, like an interface, and refer to that interface instead of CodePanel.
When it comes to ActionListener and similar interfaces, you might be interested in upgrading to Java 8, if you haven't done yet. Interfaces like ActionListener with just one abstract method are implicitly functional interfaces, which means you can use lambdas or method references.
In general, I think it helps a lot of always keeping in mind the following question: what if I replace the UI toolkit with a different one? Even if it's not a use case and would never happen, the decoupling and separation of concerns that you do in order to answer that question lead to more modular, better designs which are easier to understand and maintain. In the end, the question what if I replace the UI toolkit with a different one? leads to a design which follows more of the SOLID principles.
When dealing with ActionListener in Swing, you might want to look at interface Action and abstract class AbstractAction. They offer very interesting capabilities. Used in the right way, they can simplify code a lot.
I am just about done with our exam project, and when looking back at what I coded, I feel I did quite alright. Though, stuff could obviously always be alot better. But maybe that's just me.
I was in charge of coding the GUI, and coupling it with the application logic. When making the GUI I made the decision that I would make a class file for every window (e.g. LoginWnd.java), and actually build the GUI in the constructor. I would initalize everything and set all data inside this constructor.
Then in order to navigate through the application, I would set actionlisteners on the jbutton. For example, in SearchWnd, hitting the "Search" jbutton would create a new object of ResultWnd with some specified parameters.
Now i'm kinda wondering: Was this design decision bad in any way? Are there any design paradigms that I should've been aware of?
Thanks.
Your approach sounds fine overall - as long as it works you've achieved the main goal! So my comments here are more about fine-tuning / broader design aspects.
There's nothing fundamentally wrong with doing GUI construction in the constructor providing that the GUI doesn't subsequently change during program execution. The rationale here is that constructors should be reserved for "one-off" construction activities. So it's probably fine for dialog boxes and suchlike that have a pre-determined layout.
If you have a more dynamic GUI where components are frequently being added and removed throughout program execution, then I'd strongly suggest moving this to a set of methods outside the constructor so that they can be called independently of object construction. The constructor itself can still call these methods if needed to do initial setup, but subsequently you have the ability to call these methods later to add new components, refresh the layout etc.
The good news is that this stuff isn't hard to refactor if you get it wrong - it's usually trivial to pull setup code out of a constructor into separate methods later if needed.
Another thing to be aware of is the oft-repeated mantra "prefer composition to inheritance". That is to say, if you can make your GUI work by assembling existing components rather than inheriting and overriding your design will probably be better/more easy to maintain in the long run. For example, I don't think I've ever subclassed JFrame - it's almost always cleaner to just add JPanels within it that contain all the application-specific components.
Finally, be cautious of coupling your GUI components too closely to your application logic. Swing actually does a pretty good job of encoraging you to separate out your data model from the presentation code (e.g. with ListModel and friends). It's worth studying and understanding that approach. The point is that you should usually build GUI components in a way that is fairly application-agnostic, but give them application specific behaviour by connecting them to the right data model and event handlers etc.
I also initialize my GUI in the constructor, so it can't be bad :) But when it gets too long I extract parts of the code into separate GUI components.