Implementation of AbstractAction in the MVC model [closed] - java

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I'm developing a MVC Java Swing application, which will offer the user at least a dozen of different actions. Some of these actions will trigger execution of a SwingWorker object, while others are pretty simple (or common). I started with the approach discussed here, but I modified it in order to avoid to define an implementation of the AbstractAction class for any "common" action. This is the solution I implemented:
The Action enum class defines my "common" actions:
public enum Action {
// label mnemonic modelObject modelMethod
EXIT ("Exit" , KeyEvent.VK_E , "SubModel", "openExitView")
,FLAG_1 ("Flag 1" , KeyEvent.VK_1 , "Options", "setFlag_1")
,FLAG_2 ("Flag 2" , KeyEvent.VK_2 , "Options", "setFlag_2")
,HELP ("Help" , KeyEvent.VK_L , "SubModel", "openHelpView")
,ABOUT ("About" , KeyEvent.VK_A , "SubModel", "openAboutView");
Then, in the Controller class, I added this method:
public AbstractAction getAction(final Action action) {
AbstractAction actionImpl = new AbstractAction(action.label) {
{
putValue(AbstractAction.MNEMONIC_KEY, action.mnemonic);
}
public void actionPerformed(ActionEvent e) {
model.executeAction(action);
}
};
return actionImpl;
}
so I get the actions like following (in the Controller) and I assign them to the target Swing components:
private AbstractAction exitAction = getAction(Action.EXIT);
private AbstractAction flag_1Action = getAction(Action.FLAG_1);
private AbstractAction flag_2Action = getAction(Action.FLAG_2);
private AbstractAction helpAction = getAction(Action.HELP);
private AbstractAction aboutAction = getAction(Action.ABOUT);
private AbstractAction complexAction = new ComplexAction("Complex");
...
view.setExitAction(exitAction);
view.setAboutAction(aboutAction);
view.setHelpAction(helpAction);
...
where ComplexAction is a full implementation of AbstractAction, which is just an example of management of an action non listed in the enum class (because it's not a "common" action) but something deserving a custom full implementation.
Finally the "general purpose" executeAction method in the Model is responsible for dispatching the action to the specific sub-model class:
public void executeAction(Action action) {
Object obj = getModelInstance(action.modelObject);
if (obj == null) return;
Method method = null;
try {
method = obj.getClass().getMethod(action.modelMethod);
...
where getModelInstance just retrieves an instance of the target sub-model object from a model factory, given the model's class name listed in the enum.
Everything works fine, but I'm not convinced of this pattern: is this not boilerplate code? Are there some J2EE objects achieving the same results by writing less code? I have the feeling this is a very common pattern, and it seems strange to me that there isn't a better way do implement the MVC pattern using AbstractAction.

Create an abstract class that contains implementations of Action. The exact formulation depends on your domain, but EditorKit may serve as an example. As suggested here, concrete editor kits "export useful Action classes that operate on the Document model common to text components." More discussion may be found here, here and here.

Related

Java: How I can improve this cod e? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I made this, basically the user can toggle options to be able to see them or not in the application, i wanted to know how i can improve this class. there are parts like SEARCH & MAP that only change the value in the map and nothing else, would be better to create an abstract class and extend for each type? TypeWithoutToggle (this will only change the value in the map for the type and implement empty #toggle)) TypeWithToggle.. then extend these depending.
public enum ToggleType {
NAME {
#Override
public void toggle(VideoPlayer videoPlayer) {
videoPlayer.doToggleName();
}
},
EDITOR {
#Override
public void toggle(VideoPlayer videoPlayer) {
if (videoPlayer.isTrue("EDITOR"))
videoPlayer.createEditors();
else
videoPlayer.deleteEditors();
}
},
SEARCH {
#Override
public void toggle(VideoPlayer videoPlayer) {
}
},
MAP {
#Override
public void toggle(VideoPlayer videoPlayer) {
// handle on {#link VideoPlayer#create()}
}
},
protected abstract void toggle(VideoPlayer videoPlayer);
public void run(VideoPlayer videoPlayer) {
videoPlayer.toggleMap.put(name(), !videoPlayer.isTrue(name()));
toggle(videoPlayer);
}
You should not expose the toggleMap attribute on VideoPlayer class. Instead the should be encapsulated as a method in VideoPlayer class.
It's difficult to give a more detailed comment only by looking at these few lines.
This question is mostly opinion based, but there are at least two things that I could mention:
First is you are coupling VideoPlayer with ToggleType. There should be a separate method, probably in VideoPlayer (or a VideoPlayerToggler), that is responsible for the toggle that accepts ToggleType.
Example:
switch(toggleType):
case NAME:
doToggleName()
break;
case EDITOR:
if (videoPlayer.isTrue("EDITOR"))
videoPlayer.createEditors();
else
videoPlayer.deleteEditors();
break;
...
Let's assume that you will add a new component that can be toggled, like a MenuComponent. So it might scale better, and decouples your code. With your approach, you would have to add another abstract method, that will handle your type. In short- ToggleType doesn't have to know what or how to toggle. There might be many toggle handlers depending on your environment, configuration or other factors.
Secondly if you put this method inside VideoPlayer, then you don't have to expose any methods, keep everything well encapsulated and private, which is a good idea in general.

How to implement an action listener with generic enums?

I am in the process of refactoring my application and my teacher recommended that I replace the GUI builder generated code with a more generic one.
Right now every JMenuItem has its own action listener. What I'm trying to achieve is a sort of generic control function for every menu item by using enums in a single action listener. The code below should give you a general idea. clE is the enum key and I believe the enum should implement an interface for reading its label.
I've been doing a bit of research and I'm sure it's something simple, but I can't get fully grasp it yet. Thanks in advance!
public class JECheckBox<E extends ENUM_Label_INTF<?>> extends JCheckBox {
private final E clE;
// +++++++ CONSTRUCTOR +++++++++
public JECheckBox(final E clE) {
super( ((GetLabelINTF) clE).GetLabel() );
this.clE = clE;
}
public E GetKey() {
return clE;
}
}
I believe the enum should implement an interface for reading its label.
If you want to read the text of the check box, then you create a generic listener by doing something like:
Action action = new AbstractAction()
{
#Override
public void actionPerformed(ActionEvent e)
{
JCheckBox checkbox = (JCheckBox)e.getSource();
System.out.println( checkbox.getText() );
}
};
Now you can add the Action to each check box.
Note an Action is a more versatile ActionListener. Read the section from the Swing tutorial on How to Use Actions for more information and examples.
Not suew what you mean by generic enums. Try giving every menu item (or any component) it's own name using component.setName(SomeEnum.soneValue.toString()). Then get the name in the action listener and do a switch(SomeEnum.valueOf(name).

How to check if an enum value changed? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I'm new to Java and development and don't know how to do most of the stuff. So I wanter to ask you guys how to check if an enum value changed. So I have this:
public enum GameState {
WAITING,
INTRO,
INTRO_WAIT,
INTRO_1,
INTRO_1_WAIT,
LOBBY_INTRO,
LOBBY,
INTRO_GAME1,
GAME1,
INTRO_GAME2,
GAME2;
}
So I want to know how to detect if an enum value changed from any of those to any of those. Hope you know what I'm try to say.
Thanks :)
I assume you mean that some other class has a field GameState state, and you want to know when it changes from one value to another.
There's not an "automatic" way to do that. Have that other class make that field be private (which is a good idea anyway), and any time it changes it (for instance, via a setState(GameState) method, it can perform whatever action you want — such as calling any GameStateListener that's been registered with that class, or whatever checking mechanism you want.
It might look something like this:
public interface GameStateListener {
void onChange(GameState changingFrom, GameState changingTo);
}
public class Game {
private GameState state = WAITING; // or whatever initial value
private final Collection<GameStateListener> listeners = new ArrayList<>();
public void registerListener(GameStateListener listener) {
listeners.add(listener);
}
public void changeState(GameState newState) {
for (GameStateListener listener : listeners) {
listener.onChange(state, newState);
}
this.state = newState;
}
...
}
Note that that code is not thread-safe, and making it be thread-safe would add a good deal of complexity. There are other ways to do it, too, but the above is a pretty standard pattern.

Using MVC/MVP for Swing UI? [duplicate]

This question already has answers here:
GUI not working after rewriting to MVC
(2 answers)
Closed 8 years ago.
Till now I have worked with some java swing code with everything in one class.
I want design and develop better UI application. Trying to use MVP/MVC for swing UI, didn't found any concrete example anywhere.
I want to develop swing UI form with submit button. i.e. this main panel representing user form contains three panels:
- Header panel with combo box and text fields.
- Center panel with table pane.
- End panel with some combo box and text fields.
So basically I have written 4 UI classes with no action listeners, one for main and three for header,center and end panel. Executing Main panel show me all the components.
I want to provide runtime data to combo box and when user submit I should get selected values from combo box and other fields.
How should I design using MVP/MVC. Could any one provide some explanation or give me a link to any reference or example?
Look at this: Java - Learning MVC
The MVC pattern requires these 3 classes.
theModel: handles data
theView: handles GUI
theController: handles listeners.
You may need some understanding of the Observer pattern first.
the design may be as follows:
public class Test {
public Test(){
MyModel model = new MyModel();
MyController controller = new MyController(model);
}
}
controller class
public class MyController implements ActionListener {
private MyView view;
private MyModel model;
MyController(MyModel theModel){
model = theModel;
view = new MyView(this);
model.register(view);
}
// implement actionPerformed here
}
view class
public class View implements Observer {
private MyController controller;
public View(){
// Swing Components here
JButton button = new JButton();
button.addActionListener(controller);
add(button);
}
// notifyObserver method implementation
}
model class
public class MyModel extends Observable {
// handle state/data changes here
}

change the vtkCallbackCommand class to java vtk [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
How can i change the virtual void Execute (vtkObject *caller, unsigned long eid, void *callData) function of the vtkCallbackCommand class (vtk) to java, thanks a lot, AMAL
Adding an callback method on a specific event is different from C++. As you can see in some vtk Java Exemple you don't have to create a class which extends from vtkCallbackCommand to rewrite the Execute Method.
To add specific behavior you have to use the Java AddObserver() method, It should be something like :
public class kbHandler
{
private vtkRenderWindowInteractor iren;
public static void main(String[] args) {
kbHandler kbh = new kbHandler();
kbh.doit();
}
void callbackHandler ()
{
// if i'm here, a key is pressed !!
// you can get back information from iren (which key : iren.GetKeyCode())
}
public void doit ()
{
// Do lot of things
iren = new vtkRenderWindowInteractor();
iren.SetRenderWindow(renWin);
// add observer for the handler arg1 = event to observe, arg2 object handler of the event, arg3: method to call
iren.AddObserver("CharEvent", this, "callbackHandler");
iren.Initialize();
iren.Start();
}
}

Categories