Allowing two classes to share variables and methods - java

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)

Related

Is it bad design using static variables for core parts instances?

Developing a jogl application, this is (a part of) our core class structure
main jFrame
viewer (for rendering)
inputListener
viewpole (for camera/projection control)
graph (holds nodes/meshes)
icon handler (to expand/collapse a node with children)
So if I want to call methodX() in the icon handler(that is basically the texture representing the handler, it is the same for all the nodes), I have to call:
Main.instance.getViewer().getGraph().getIconHandler().methodX()
where instance is a static variable holding the instance of the main jFrame
Given they are all:
1) instantiated once
2) at the begin
3) are supposed to be there for the whole time
4) in theory, no problem of race conditions, we are using java.util.concurrent.locks.ReentrantReadWriteLock at lower level when we add/read/modify/delete nodes
is it dangerous/bad design assigning the instance of each class to a static variable inside each corresponding class?
so that if I want to access the same methodX() I would just call
IconHandler().instance.methodX()
Ps: I read some of the other questions regarding static variables() but I found them quite generic, mine regards the core parts.
As long as you know that you'll only ever need one instance of each class, this is okay. This is called a singleton and is a pretty well-known design pattern.
The problem is that you probably can't guarantee that you only need one instance of your classes. Singletons are good for things like data connections or file readers, where there is a built-in limit to the number of instances that should access the data.
You're misusing the static keyword as a lazy way to gain access to an instance of a class, and it's going to come back and bite you when you expand your program to include multiple instances of those classes. And if you think you'll only ever need one instance- you can't guarantee that will never change.

Is it an ok practice to have a member ClientBundle in a containing ClientBundle?

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.

What's the proper way of declaring project constants in Java?

This may seems a silly question for Java developers, however, I'm new to Java, and my background is from low level c.
I used to include an header file with all the constants that were relevant for my projects. (usually #define's).
I'm working on a big Java project now, and there a few constants I need to make global (they fit in more than one class, and used in various parts of the project )
It makes it hard for me to decide where to put it, should I declare the same constant few times, one in each class ?
A lot of framework, uses XML files to declare constants & definitions for the framework (Hibernate, Log4J, etc.) Is it wise to use this kind of technique in my project ? if so, how can it be done easily ?
As with many things, there are many ways to do it. One thing you should not do is declare them multiple times - that's just plain silly. :P
Everything has to be in a class in Java, so either:
Pick a "main" class (say I have a project called "FTPServerApp" - I could put them there)
Create a "Util" class that contains all of them
When you figure out where to put them, declare them all this way:
public static final [type] [NAME_IN_ALL_CAPS] = [value];
This will
make them available to all your project code, anywhere (public)
only one copy of the value exists across all instances of the class (static)
they cannot be changed (final).
The ALL_CAPS_FOR_CONSTANT_NAMES, separated by underscores, is the convention in Java.
So, if this was declared in a class called FTPServerAPP, and you had a constant called SERVICE_PORT it might be:
public class FTPServerApp {
public static final int SERVICE_PORT = 21;
...
}
...and you would access it, from any class, like this...
FTPServerApp.SERVICE_PORT
Take a look at enumeration types (http://download.oracle.com/javase/tutorial/java/javaOO/enum.html) They are supposed to provide a mechanism to supply constants without defining a concrete class (or an Interface with the desired constants, as is another option that people use).
One other technique I find helpful (similar to the FTPServerApp example given above) is to define a Context for whatever subsystem/component/etc... that holds not only the constants needed by components in that system, but can hold any state that you want to make more visible or don't want individual components to hold. I believe this is along the lines of one of the GoF patterns, but it has been so long since I have looked at that book that I can't be certain (and I am too lazy to look it up right now!)

Is it good programming practice? Constructors and instance variables

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.

Questions regarding Extending JFrame in a class?

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...

Categories

Resources