I am (supposed to be) creating a simple menu display. My Menu class creates a List of MenuOption objects and these can be displayed and selected, etc. A programmer can add options to the List in the Menu class, optionList, using the addOption method.
What I want to be able to do is make it so the programmer can associate any arbitrary method from one of his or her other classes with a specific option.
For example, I want it so if the programmer typed something like:
menu.addOption("Print a roster", roster.print());
then the addOption method would do something like this:
optionList.add(new MenuOption("Print a roster", roster.print()));
and then, henceforth, the method roster.print() would be associated with the menu option text "Print a roster" so if a user chose "Print a roster," roster.print() would be called.
===============================================
By the way, I have started looking into the new Lambda Expressions from Java 8, but I'm not quite sure how they work or if they provide the necessary approach I would need to achieve my desired effect.
Any help is appreciated, thank you!
The second parameter to the MenuOption constructor would have to be a Runnable, and you would be able to supply
roster::print
as a value. This is called a Method Reference, and is just syntactic sugar for creating an object that implements a Functional Interface (in this case Runnable). It could also be written as
() -> roster.print()
On button click you would need to call the run() method.
Related
In my application I have a main form which has buttons to process other actions, for example my main form displays a list of all entities in my system, and a user is then able to select and then Add or Edit those entities in the application.
When a user presses "Add" a new JFrame is opened, allowing them to add to the system. This is all fine, however I am having a small problem which is affecting some functionality.
I wrote a CommandTracker which allows me to undo and redo operations, the library works fine however I am struggling to reference the CommandTracker object on my main form from other forms. (hopefully code shall convey my question better)
Main Form Declarations:
protected CommandTracker;
// This is instantiated in my constructor, trying to show less code to keep simple.
objCommandTracker = new CommandTracker();
This instantiates my new Command Tracker object within my main form, I would then like to reference this object from my subform so that I can append the next command fired in my sub form.
So far I have tried to resolve this by providing a reference to my main form within my subforms .java file
protected static MainMenu main_menu = null;
I then tried to access the command tracker as follows
// Run AddRequestCommand, through the command tracker
mainMenu.objCommandTracker.executeCommand(addCommand);
However, this results in a null pointer Exception being thrown, I assume this is because mainMenu has a null reference in its declaration. How do I go about passing the current active MainMenu instance to my subform?
Use of statics is never the way to solve something like this. The solution is to pass valid references where needed and to call appropriate methods on these references.
So in other words, if one class needs reference to another, then pass the reference in via a parameter, either a constructor parameter or a setter method parameter, use it to set a field, and then you are free to call methods on that reference in that class.
As an aside: at some other time we'll need to discuss the problems with shooting multiple JFrames at the user, and at your atypical use of the term "form" as if it had a standard meaning in the Swing library -- it doesn't, and so you'll want to use other clearer terms.
If one has no intention of using a parameter in C++, one simply omits the name of the variable but keeps the type in the function declaration. Doing so is a light-weight method to signal to the compiler that one intends not to use a given parameter.
Is this possible to replicate in Java?
The scenario is this: I would like not to flood my code with #SuppressWarnings("unused") for every single button listener (because button listeners most often ignore the View v they receive), and yet I would like to be warned in general about the silly mistake of, say, not initializing a member variable by a parameter.
I can't think of anything like the C++ option but you could extend/implement your button listener and add a new method without the parameter and have that method called in the original event method. This way you will only have to suppress warnings once.
public void someEvent(Parameter p) {
someEvent();
}
public void someEvent() {
}
In addition to creating an adapter like #Farzad suggested, you might want to also check your compiler settings in your IDE. For example, I use Eclipse and there are error/warning compiler settings under Window->Preferences->Java Compiler->Errors/Warnings. Within that dialog you can set UnnecessaryCode->Value of parameter is not used->Ignore in overriding and implementing methods.
Having that option checked automatically ignores those unused params when they are from a method that you are implementing/overriding such as in your listener case. I generally find that to be sufficient without needing to create an adapter.
I'm a student and I'm new to Java, this assignment I am doing is the first assignment I have to do that has to strictly follow oop conventions. So this may be a newb question. When coding a menu, would it be appropriate to put the menu code in the main method or should it be in a class and instantiated along with everything else?
EDIT:
The menu menu is a simple command line menu that is inputed with numbers, no gui. Not that far yet.
If you want to strictly follow the OOP convention you could have your own class like
abstract class MenuItem {
int index;
protected MenuItem(int index) {
this.index = index;
}
abstract void action();
}
class ExitMenuItem {
ExitMenuItem() {
super(3); // the index value of the menu item
}
void action() {
System.exit(0);
}
}
So that you can have a subclass specific for every menu item that has its behavior.
Then you could have a menu container, something like:
class Menu {
ArrayList<MenuItem> items;
void executeAction(String input) {
..
}
}
that should understand which voice has been chosen according to the stdin input and execute it. Of course you can enrich everything by having a default text for every menu item and whatever. Then in your main method you just instantiate the menu and take care of forwarding stdin input to it.
Mind that this is usually overkill in a simple menu but if you want to understand OOP then it's a nice way to go.
For a Object-Oriented approach, you should create the menu in the specific class. Main method is a legacy of Procedural/Imperative programming languages. Main method should just run the main thread.
It depends. That's usually the worst answer one can provide, but unfortunately, it fits perfectly.
You haven't provided the full requirements so it is a little difficult to guess what you are intending. Is this menu specific to a single class? Can it be run multiple times? Should it be able to be run in parallel?
Or rather, is this menu just an entry point into the actual program? ex: press 1 to login, press 2 to display something on screen, press 3 for ....
The reason I am giving you these questions is because they will shape the structure of your code. In the first case, if they are menus related specifically to a class and can be run from multiple locations in the code at multiple points, then it would make sense that the belong within the class structure itself (non static).
However, if the menu is purely an entry point into the application, it would make sense to either put them in the main() section of the code, or code another static method called menu() for clarity. But realistically, the menu() method would only get called from the main.
The next thing to ask yourself is how you plan to validate the responses from the menu selection. Do you need complicated/involved code? Does it make more sense for the validation routines to be part of the main method or have their own methods? Does it make more sense to have member variables to communicate between method class to validate, etc?
Keep in mind that static methods can be called without instantiating the class. That being said, a static main() method or static menu() method still remain within the class itself, and are part of OOP design.
Ask yourself this - if putting codes that prints menu in the main method, how do I handle printing multiple times?
If putting codes into methods in the same class as the main and I need to print menu somewhere else probably in another main class, how do I handle that?
Eventually, you will have a class that handles code dealing with displaying of menu, and the main class would only be calling on methods of that class. :)
Probably there are different tastes to this, and a good answer might also depend on what your app is doing.
First, for a small application I wouldn't mind having the menu in the main class.
But then for nice structure, it is a good idea to have a class that is responsible for printing the line-based menu and then of course also for reading the user input and invoking the action the user asks for. I think a good idea would be to call such a class Controller or Dispatcher. This class would be a singleton. Further I would think it's a good idea
to have a method displayMenu and dispatch. Both would be called from the constructor consecutively.
How dispatch is then calling the appriopriate action will depend on the rest of your app.
Some people don't like this style, as your main routine will probably have declarations only.
Please allow me to explain what I am trying to do - I think that the title explains it roughly, but I am none too sure that I am going about things the right way, so please correct me if I am wrong!
I have created a custom dialog using a LayeredPane. Essentially a jPanel is shown on the POPUP_LAYER, thus appearing over the top of the main content. This panel contains a simple 'label-textbox-okay-cancel' group of controls. I will call this the 'Dialog Panel'.
What am I trying to do:
When a button is clicked on the main window (contained within the LayeredPane), the Dialog Panel will appear and allow the user to enter some text, then click okay or cancel. This is all easy enough, but I would like this code to be re-usable, which means that other buttons on the main window will invoke the same Dialog Panel, but with different text in the label.
This of course requires me to include some kind of callback function so that the okay button on the Dialog Panel will run the correct code, according to the button which invoked it.
My current attempt is to store a string which will contain the name of the function that should be run when the user clicks the okay button on the Dialog Panel. I am attempting to retrieve this string and convert it into the function name and so far I have found many references to 'Reflection', many of them suggesting that it is not a good idea.
In any case I have been unable to get any example code to work because I do not understand what the 'obj' is in the code below and am unable to invoke the method:
method = obj.getClass().getMethod(myCallbackString);
My questions are:
Firstly, am I even going about this the right way? I am more than open to suggestions, but please try to keep it as simple as possible because I really am just getting started!
Secondly, what is the 'obj' in the code shown above? I would really like to know, even if this is not the way that I should be doing things!
My other thoughts include: Should my Dialog Panel be in its own class, and if so, again, how to pass the callback function?
Any help or advice would be gratefully received.
BTW: In answer to the question "why not use a normal dialog?" I can only say that I am currently experimenting, and I simply want to see if I can do this!
MVK
The usual way the callback functions are passed in by Java programs is by passing instances of interfaces that implement a specific callback function. It is typical, though not required, to implement the interface anonymously.
For example, here is an interface:
interface MyCallback {
void performCallback();
}
Here is the way you define your dialog's method that takes a callback:
void openWithCallback(MyCallback cb) {
// Do something useful...
...
// Perform the callback
cb.performCallback();
}
Here is the way that you invoke that method:
public void OpenDialog() {
myDialog.openWithCallback(new MyCallback() {
public void performCallback() {
System.out.println("Inside callback...");
}
});
}
obj names the object whose method you want to call, in your case you can probably replace it with this (or drop it out entirely, since this is implied):
private void callByName(String name) {
try { getClass().getMethod(name).invoke(this); }
catch (RuntimeException e) { throw e; }
catch (Exception e) { throw new RuntimeException(e); }
}
For this to work you need to declare a public no-arg method with the appropriate name.
I think your idea is valid, although it has a major drawback: you store the method names as simple strings in your code, so the compiler can't check them for validity. Therefore, if you change the name of a method, you manually have to make sure you have updated all the strings referencing it.
This is what's usually meant with 'reflection is a bad idea'.
obj in your code is the object on which you want to call a method. As a simple example, the equivalent of someInteger.toString(); with reflection would be someInteger.getClass().getMethod("toString").invoke();.
On a more generic note, once you're comfortable with Java, you might also check out a functional language like Scala, where functions are regular objects, and the scenario you intend could be implemented with full compiler checking.
I think that you're making this way more complicated than it has to be. You said you want this:
This is all easy enough, but I would like this code to be re-usable, which means
that other buttons on the main window will invoke the same Dialog Panel, but with
different text in the label.
A DialogBox is, by definition, reusable. Why don't you just have the button click listener pass the appropriate text to the dialog box when clicked, so it shows the correct information?
If you need specific actions to happen after a button click on the dialog depending on the invoker, you may want to consider:
Created a custom DialogBox extension that includes logic that knows what to do based on who called it. Then when a button invokes the custom dialog, it would pass it a parameter to let it know what it wants to do after the dialog box is dismissed.
Look into using something like the abstract factory pattern.
Yes, you could do this via reflection. Yes, it would be a very bad idea, for many reasons that other people have discussed in other answers, especially if this is production code (though you seem to indicate it's an experiment.)
If you really just want to see how to work it with reflection, you'll probably want to read up on that topic. I found this to be one of the better tutorials out there.
I haven't worked with JPanel, but what I understand form your query, answer seems rather simple. Instead of passing method name, why dont you work on interface and pass the different implementation of that interface?
I am trying to get round a rather annoying issue in my homework.
Basically the task is to create a fake ordering UI where the user puts in some variables about the type of box they need to order and then presses a button. Behind the scenes the app should be validating which pipe fits the users needs and then instantiate a new box object and execute the methods inside the new object.
I am basically struggling to find a way that isn't stupid which allows for the UI to validate a choice before creating a new object, a method is given to us to begin with and is referred to a 'brute force method' which has a massive if statement inside the button click which does the checking there, now I am 100% sure there is an easier way to do it although the only thing I can come up with is holding constants or statics in a class and checking each class before creating one.
Scenario:
The idea is that each box the company sells has certain features (thickness, laminated, colour and other things) while others boxes don't, I need to be able to figure out when the order button is clicked what box the order fits once I know the box type that the order fits I should create a new object of that box and run the cost() method, if it doesn't fit any box the company sells then I should prompt the user. The program must use abstraction.
The class isn't at a high level at the moment so I can't use enums and lookup tables which is causing me problems.
Thanks for any help in advance.
Sounds to me like they just want you to show several classes (one for each type of box) which all inherit or implement a common interface with methods like 'getWidth', 'getHeight' etc. You can then write a simple loop to iterate over a collection of box type instances, evaluating their suitability before returning the list of compatible box types.