In Java, would it be a bad programming practice to do anything other than instantiate your instance variables inside your constructor?
I'm making a GUI right now, and I was thinking about coding the GUI building inside the constructor so that in my main, I can just make a new instance of the class to start the GUI.
That is exactly what constructors are for. The aim of a constructor is to initialise things so that the instance now exists in a program it expects to be in.
For example if you create a Window class an instance might expect to also have a Content instance and so on. However this process is not limited to things you hold a reference to using instance variables.
It's generally a good idea to package things into small/concise and understandable units.
The constructor is where intialization happens. If you're worried about writing too much code in there, you can package the UI init code into a method (call it initUI() for example) and call it at the end of your constructor
Constructor is meant to initialize your object. Now, if initializing your object need to initialize instance variables and/or call some methods or have some logic in it that's alright -- nothing wrong with that.
One of the practice that I like is not to bloat the constructor. Instead, divide the initialization code in logical chunks in separate methods and call them from inside the constructor. Like in your case,
public class MyClass{
public MyClass(){
this.myVar1 = new myVar();
...
buildUI(param1, param2,...);
}
//can make it public if you think this method can call to repaint or something
private void buildUI(Param1 param1, Param2 param2,...){
....
}
}
Don't forget the Builder Pattern. This pattern is designed to allow you to "build" your objects.
In Java, it is common practice to override classes such as JPanel and add the building logic internal to the constructor, in which case the class is self-building. It is also possible to create your own class that simply returns a JPanel fully constructed which is my preference. Example:
public class MyJPanelBuilder {
public JPanel build() {
JPanel panel = new JPanel();
// Add all your components to the panel, lay it out how you want etc.
// You can do it this way because all of the methods required are public!
return panel;
}
}
I prefer this approach as it makes it harder to violate MVC if you are simply using the widgets as supplied by the JVM.
Similarly to RAY I would advice to keep components small and focused.
To make statements of Nishant and Markus more precise, the constructor is supposed to leave the object initialized, but you actually have choice how to do this.
I am usually against instatiating collaborating objects from within a constructor directly (via new operator) or indirectly (via private method call), because that makes testing harder. Sometimes you want to substitute a collaborator for a fake one to find the source of a bug. If you use new operator or a private method, you won't easily do it.
Therefore I lean to passing dependencies to my constructor via its parameters from some external place (a factory, or a builder, mentioned by Bringer128). Your constructor expects the parameters to be already initialized, so after assigning them to the object's fields, the object is ready for use.
Of course in case of dependencies, that you'll never need to substitute it's easier and still safe to instantiate them directly inside the constructor. Especially in GUIs there'll be a lot of that cases (labels and such). However should you have a dependency from outside the GUI layer (like business object), I would definately not create it in the constructor.
Related
So I'm trying to keep my program more organized. To do this I have on file containing my methods and the other has the event listeners and variables. The second file needs to use methods from the first file to change variables and whatnot. The first needs to use variables from the second to run properly. Basically:
public class Controls extends javax.swing.Jfarme{
int turns = 0;
int stuff = btnSet(jButton1);
}
public class GamePlay{
public int btnSet(javax.swing.JButton btn){
//do stuff using turn
turn++;
}
}
Do this make sense? How can I let these two share?
EDIT: I want two classes to keep it better organized. I made TicTacToe, then TicTacTwo, and now TicTacCube. It is simply getting a bit messy (I now have 243 JButtons to keep track of). I just want to split my methods from the code being executed to be pretty.
Disclaimer: of course, there are many ways to design the classes architecture of an application, so the following is just one way (but not the worst) to do it.
My impression is that you haven't adopted the concept of object-oriented design and programming.
If you describe the (gaming?) application to someone else, you'll surely use a lot of nouns and verbs. A rule of thumb is to make classes out of the nouns, and methods out of the verbs. I guess that the words "Controls" (especially as it's plural) and "GamePlay" won't be the most prominent ones in your description, so don't start there. Instead I'd expect nouns like "Player", "Board", or "Figure", and verbs like "move", "collect", "shoot" or whatever your game is about. For the verbs, becoming methods, you have to decide in which class they belong, and you do this mainly by answering the question who or what is the subject of the sentence, so e.g. move() should become a method of Figure, as it isn't the board or the player moving, but the figure on the board.
When further designing the classes, concentrate on the inner workings (the "business logic") of the entities, and not the user interface - that should be kept in distinct classes.
So, a decent design of such an application might hava a GamePlay class with the top-level workflow of the application, but GamePlay shouldn't have any user interface (javax.swing.*) elements in it. The user interface (maybe something like your Controls class) should communicate with GamePlay and its companions only by calling some of their methods, not by reading fields.
P.S. Regarding questions on StackOverflow: it's preferred to copy parts of real code into questions, so you avoid typos like Jfarme instead of JFrame.
For it to work with your current design:
To use btnset() function from the Controls class, import the GamePlay class into the Controls class, then instantiate a GamePlay class object to access its btnset() function.
ex. GamePlay gameplay = new GamePlay();
gameplay.btnset();
To use the turns variable in the GamePlay class, import the Controls class into the GamePlay class, then instantiate a Controls class object to access its turns variable.
ex.
Controls controls = new Controls();
controls.turns++;
Alternatively you could make the method or variable static so you don't need to instantiate an object first. If the method/variable were static you could just call GamePlay.btnset(); or Controls.turns++;
As far as I can tell, there are effectively two ways you can do this: statically, or using objects (java is an object-oriented language after all)
Statically
A static approach to this effectively means that all variables and methods belong to the classes themselves. This would require putting the keyword static before all variables in the Controls class and all methods in the GamePlay class. These would all then be accessed by ClassName.variable or ClassName.method() e.g. Controls.turns or GamePlay.btnSet(btn)
Using Objects
This approach means that new instances of your classes are created, each of which hold their own instance variables and methods, which would be accessed using instance_name.variable or instance_name.method(). This would involve creating instances of the classes, e.g. Controls controls_instance = new Controls() or GamePlay gameplay_instance = new GamePlay(), and then referencing their attributes, e.g. controls_instance.turns or gameplay_instance.setBtn(btn)
I'm a beginner in Java programming and I'm currently working on an app with more complex class structure and a GUI. This might be a stupid questions, but it is very hard to google, so I'm asking here.
I have a main class, looking like this:
package app;
public class App {
private FirstClass fc;
private SecondClass sc;
public App () {
fc = new FirstClass ();
sc = new SecondClass ();
// ... code continues ...
}
}
Say the SecondClass is defined outside of this .java file (like GUI forms are). Is there a way for me to access the "fc" instance (or other member variables of the App instance) from the "sc" instance (without passing the "this" pointer)? Something like:
class SecondClass {
public void someMethod() {
getWhoeverCreatedThisInstance().fc.getSomeData();
// ... code continues ...
}
}
And if not, what am I doing wrong? Should I design this differently? Maybe setting the "fc" as static? But what if I want more of my app's classes to communicate with each other, should I make them all static? What would be the point of having something non-static then? I could pass the "this" pointer of "App" or "fc" instance in the constructor of "SecondClass", but that solution just seems non-elegant when the number of classes that need this behavior rises.
Any ideas? Thanks in advance!
My suggestion is to implement a callback system with interfaces. Each of your classes communicating with each other should implement these.
The classes should Register to the creating class.
Then they can call a method in the creating class which invokes the interface method of each registered class and passed the data this way.
This SO answer might help
https://stackoverflow.com/a/18279545
If you want to develop GUI applications, you should really get into the basic concepts. This can be very time-consuming, but it is necessary, otherwise you will encouter strange behaviour. I will just give you a basic understanding to answer your question.
You think of simple console applications, where you usually have a single thread and passing around objects is valid. With multiple threads, this is fatal, even with static variables. Each variable or object can be modified concurrently and the other thread may not be able to 'see' the changes in time. This is a complex matter, since there are also caches and separate stacks for each thread. In short, fc may not always be synchronized in App and sc, therefore reads and writes may be inconsistent.
What to do now? Learn the concepts of GUI programming. Often you do not even have to share objects for simple things. If a GUI control triggers an action, use a Listener, look here. If you want to access a database for example, then just make a new connection object for each request or button click, whatever. This is simple to start, add complexity later.
A simple variant to share objects is to use the synchronized keyword, which ensures that a method or a field is only accessed by one thread at a time. Here is an example. Also look at thread-safe data structures provided by Java (java.util.concurrent).
For advanced purposes you would have a separate thread and you would connect them with Sockets to pass messages or data.
In my app, I have MyAppResources, which will mainly contain custom styles for the app. I am thinking about what is a good way to go about applying custom styles to standard widgets, such as a CellTable, along with custom styles on the layout and custom widgets?
My question:
Since MyAppResources is a singleton (it doesn't have to be, as mentioned in other posts), but CellTableResources isn't, and CellTableResources is a member of this instance that is an interface also extending ClientBundle, will a proxy 'CellTableResources' be created on every MyAppResources.INSTANCE.cellTableResources().foo()?
If so, could I create a MyAppResources.CELLTABLE_RESOURCE_INSTANCE to get around this? Or would the creation of the proxy be negligible, even if there are plentiful calls to MyAppResources.INSTANCE.cellTableResources().#?
Secondly, more of a discussion question: what is best practice in regards to using multiple ClientBundles in this case? Should I instead use CellTableResources seperately (remove it from MyAppResources), using GWT.create(CellTableResources.class); in a widget that needs it (or using a singleton like I have for MyAppResources)?
MyAppResources:
public interface MyAppResources extends ClientBundle {
public static final MyAppResources INSTANCE = GWT.create(MyAppResources.class);
#Source("MyAppStyles.css")
public MyAppCssResource css();
public CellTableResources cellTableResources();
}
CellTableResources:
public interface CellTableResources extends CellTable.Resources {
interface CellTableStyle extends CellTable.Style {
}
#Override
#Source({ CellTable.Style.DEFAULT_CSS, "CellTableStyles.css" })
CellTableStyle cellTableStyle();
#Source("green_light.png")
ImageResource getGreenLight();
//...
}
Thank you for reading.
Multi-part question, so I'm going to try to hit this in several parts:
What is the cost of GWT.create()?
Most of the GWT class is 'magic', things that you cannot wrote for yourself in other ways, as they call on the compiler to fill in specific details for you. These are often different when running in dev mode vs compiled to JS.
In the case of GWT.create, it turns out that this is compiled out to new - it is used just to create new instances. So what is the cost of a new instance versus a singleton? This depends entirely on the object being created. If there are no fields in the object, then the cost is essentially free - in fact, the compiler may choose to actually remove the constructor call, and rewrite all later methods as static anyway!
This is what happens in most cases - GWT.create should be considered to be very cheap, unless you are doing something silly like calling it within a loop that is run many times.
What happens when I list a ClientBundle method inside another ClientBundle?
Well, what happens when you list anything inside a ClientBundle?
Anything that can be listed in a ClientBundle must be annotated with #ResourceGeneratorType, indicating how to generate that type. For example, here is ImageResource:
/**
* Provides access to image resources at runtime.
*/
#DefaultExtensions(value = {".png", ".jpg", ".gif", ".bmp"})
#ResourceGeneratorType(ImageResourceGenerator.class)
public interface ImageResource extends ResourcePrototype {
//...
It calls on ImageResourceGenerator to create images as needed. Any class described in that annotation must implement com.google.gwt.resources.ext.ResourceGenerator, which describes how to get ready to work, how to create necessary fields, how to initialize them, and how to finish up.
So what does this look like for ClientBundle itself? Check out com.google.gwt.resources.rg.BundleResourceGenerator - it is a very simple class that just calls GWT.create() on the type of the method given. So, predictable, this means that those 'child' ClientBundles are created via GWT.create, more or less the same as you might otherwise do.
Okay, what does that mean in this specific case?
It turns out that ClientBundles instances don't have fields where they track newly created objects from, but instead have static members that they use instead - effectively singletons. This means that once you have called a method once, the instance it returns will be the same instance created as the next time you call it. Two different ClientBundles with the same contents will of course then keep two different copies of the objects, but it doesn't matter how many times you create a ClientBundle - its internals will always be the same.
Anything else?
Yep! Remember that you are dealing with interfaces here, not classes, so you can actually extend more than once at once!
public interface MyAppResources extends
ClientBundle,
CellTable.Resources,
CellTree.Resources {//etc
//...
Now, if two interfaces describe the same methods you may have problems, but if not, this can provide an advantage when generated sprited images. Each individual ClientBundle will draw on its own pool of images when preparing them for use - if you have a ClientBundle within a ClientBundle, they won't work together to sprite images into bigger pieces. To get that, you need to make just one ClientBundle type. This may not matter in your particular case, but I figured it was also worth mentioning.
I have been perusing the open source code of JMapViewer. If anyone else wishes to look at it, check the SVN.
In a nutshell, the main class is JMapViewer, which is an extension of a JPanel. There is another very important class called DefaultMapController which acts as a MouseListener for the main class.
The first weird thing I noticed is that the viewer has no references to the controller. The JMapViewer constructor instantiates an anonymous instance of the DefaultMapController, like this:
public JMapViewer() {
// other stuff
new DefaultMapController(this);
}
This seems to me to be a poor design choice, since the controller has tons of methods (options, toggles, etc - example shown below), which now can not be accessed at all, so what good are they?
public void setMovementMouseButton(int movementMouseButton) {
// changes which mouse button is used to move the map
}
The controller does have a reference to the viewer as shown in the first snippet above, which is how it is able to exercise control.
However, then I thought of something even weirder! If this anonymous instance of the listener has no references, why is it allowed to even survive? Shouldn't the GC destroy it quickly? Or is GC smart enough to know that a listener class which references a live JComponent must also stay alive to work properly, even if it has no name for some strange reason?
So, two real questions:
why does GC not destroy object?
is this indeed a poor design choice, or is there some way I'm unaware of to access the controller from the class which instantiates the viewer?
I want to contribute to this open source library, and my first idea for a change is to change the JMapViewer class to have a field referencing its controller, and to change the constructor to assign the currently anonymous controller to this new field. But, I want to make sure I'm not ignorantly missing something. I have searched the entire codebase for the text DefaultMapController, and it only occurs in its own class definitions, and in the anonymous instantiations in the JMapViewer constructors.
EDIT:
It does indeed appear that there is a way to access the anonymous listeners, by using the java.awt.Component method getMouseListeners(). So technically in my application I could search this collection for instances of DefaultMapController, and use that to access the methods I need to use to change the controller options.
To play devil's advocate though, if I go with original idea and give the map a reference of its controller, now I have a sort of circular reference (map knows of controller and controller knows of map). Is this a bad idea?
The abstract parent, JMapController, holds a reference to the JMapViewer passed there by the DefaultMapController constructor:
public DefaultMapController(JMapViewer map) {
super(map);
}
Addendum: The map reference held by the controller is used to (selectively) add up to three controller references to the map's EventListenerList, discussed here. Any one of these would preclude GC. At least one salutary design benefit is that a concrete JMapController need only implement available interfaces.
As suggested in this MVC outline, it would be unusual to give the view a reference to the controller. In contrast, there's nothing wrong with letting the controller register as a listener to the view, as suggested here.
Note that only the no-argument JMapViewer constructor installs a DefaultMapController. You can use the alternate constructor, as noted in comments at line 57-59 in revision 29113 of Demo.java. A complete example is examined here.
1) Everything you know is that, if and when the VM deems it to be appropriate, it will collect some or all of the dead objects. The GC is not required to do anything.
2) The best thing is to ask to the maintainer of the library. Anyway, as a general rule, I would not bother to change anything unless there's a good reason to, e.g. if it sensibly improves readability, and would rather focus myself on real problems.
3) Not sure if that's the case, but, when you serialize a JComponent, you also serialize all of its fields. And you do not want to serialize a lot of unused stuff.
Okay, I'm NOT a Java noob, it just so happens that I've forgotten a tad bit about core Java while I was learning more fun stuff like MySQL, Servlets, Java EE, JDBC etc etc; so don't frame your answers as if I were a beginner. Now the question.....
I'm writing a class (lets say ThisIsAJFrameExtendingClass) which extends JFrame, and to minimize confusion with my overall project, I also want to park some other utility methods in ThisIsAJFrameExtendingClass. I intend this class (ThisIsAJFrameExtendingClass) to seek certain inputs from the user following which; commit suicide (ie dispose()). So, my question is, how can I independently use the utility methods inside the class without any JFrame popping up on the user screen.
I'ld like a solution with the help of multiple constructors inside the ThisIsAJFrameExtendingClass class, where, invoking the argument-less constructor return JFrame and the second constructor with a boolean argument gives access to the utility methods.
[UPDATE]
Ohh.... I just had a thought, the utility method has a return type of ArrayList so, assuming the utility method is called utilMethod() then:
ArrayList<String> pring = new ThisIsAJFrameExtendingClass().utilMethod();
will the above code output any JFrame?
You could make the utility methods static, in which case they can be invoked using ThisIsAJFrameExtendingClass.<method name> without creating an instance.
The stuff about constructors doesn't really make sense to me. A class's constructor always returns an instance of that class. It can't return "something else" because of a parameter you pass in.
[Edited to respond to the question's Update]:
new ThisIsAJFrameExtendingClass() will create an instance of your class, running its constructor (and the default constructor of all superclasses). This may allocate other resources (such as other Swing components or whatever) that each constructor in the inheritance tree requires. So a JFrame is created, but if you only call utilMethod() and never hang on to the reference to the frame, it will be garbage collected and its resources freed at some point in the future.
Creating a JFrame instance to call a single utility method on it isn't a particularly efficient way to go about things, but it won't cause any problems. (As Chad says, by default a JFrame isn't visible, so users won't see anything if you're using it in "util" mode).
As to returning an ArrayList, as a general rule when using collections, you should return the highest level interface that makes sense rather than a concrete class. So in this case, consider returning List<String> or even Collection<String>.
I have a lot of trouble getting behind your concept, which sounds a bit confused to me. At the very least, it sounds like horrible design. But I do have some suggestions:
You can make those utility methods static, then you won't need to instantiate your class at all to use them. This would be the simplest case.
You could pack your utility methods inside a static inner class of your frame, which essentially gets you around the requirement to only have one class per file.
Finally, do you just want the JFrame to disappear once the user is done with it, or do you want to terminate the application? dispose() will do only the former, your app will continue to run as a kind of headless zombie process.
Okay let's assume the methods you need aren't static.
In that case, remember the JFrame won't show up unless you call setVisible(true); So just make sure you never show the frame, and you can use whatever functions you want without it annoying the user.
Or you could design it properly and break out the utility methods into a separate class...