in a définition of a widget, what is a better practice, and why, use the widget himself or the type "higher", example, it's a better practice to do
1) Button myButton;
or
2) Hastext myButton; (and set a button later)
thanks for your answer.
It is usually a good idea to use "higher" types or interfaces. By doing this properly you can hide implementation details. The code that uses an object looks at it as the one of a higher type and it is not important what is actually hiding behind it. This is good because you can easily change an implementation of the object without breaking anything.
For example when defining a panel in an application you should use Panel class instead of its implementation e.g. HorizontalPanel or VerticalPanel.:
Panel myPanel;
Then you can create a proper implementation of it, e.g HorizontalPanel:
myPanel = new HorizontalPanel();
If you then later decide to change myPanel to be VerticalPanel you will not have to change anything in the code that uses myPanel. Everything will work just fine.
However you must remember that you will be only able to use methods available in Panel class. Additional methods defined in e.g. HorizontalPanel will not be accessible. And this is actually what you should remember when choosing the type of your widgets. Your widgets should be of types which provide methods which you want to use.
In your example using HasText instead of Button isn't probably a good idea because HasText has only methods for setting and getting a text and you probably also want to have access to addClickHandler method available in Button and a few more.
So to summarize it is good to use "higher types" but they should not be "too high" to be useful.
The answer to that lies in the Model-View-Presenter pattern, that was introduced in last years Google IO presentation by Ray Ryan. There's also an official tutorial/docs - part 1 and part 2. There are also a number of questions here on SO that cover that topic :)
And a quick answer to your question (that will make more sense once you get familiar with MVP): use interfaces in the Presenter and their implementations in the View :) That way your Presenter stays oblivious to the underlying implementation/Widget you actually used (was it a Button? Or a Label? It doesn't matter, they both implement HasText).
Related
I'm working on a game (in Unity3D) which consists of a dozen menus and no real 2d/3d game world. From a programmer's perspective it is just a bunch of buttons, labels and images.
To not have everything inside of one big menu class, I decided to split the code in parts for every menu. The result is that I've got a dozen classes which themselves have all the references to their gameobjects and e.g. the button methods.
My problem is that almost everything in my project is static by now, because these menus do not get instantiated multiple times and I have to access variables and methods from one menu with the script of another menu.
Thus my question is what the best practice would be for this situation. I've got a couple of ideas, how I could do it, but unfortunately I didn't get to learn what to do in such a situation.
So if you straight up want to suggest something, feel free to do so. :)
My ideas:
1) Make a controller which has static instances of all menus. A button-method in class 'A' could then call Controller.B.x. This does work, but I dislike putting "Controller" everywhere so often, because most classes access methods and variables from other classes so often, that it's just ugly.
2) Make these menus all be singletons. Afaik are singletons "ok" for something like this, but aren't they just shifting the static instance to their own class instead of one controller? When I switched from option 1) to this with one class, basically Controller.A.x became A.instance.x, where "instance" is the static instance of the class inside the class.
3) Keeping everything the way it is, having variables and method being static whenever I need to access them statically from another class, otherwise make them private.
The game is probably not a "bunch of buttons, labels and images".
I suggest to forget about the menus for a second, focus on the model of your game, create classes strictly for that. You don't put things like "how much of a currency does the player have" in any menu, it should exist in a Player class or similar (the model).
Once you can manipulate your model from a single test controller class, and simply log the results in debug console, you're ready to do the same with menus.
After that, you can much easily create user interfaces to read /display (creating labels and images on the fly) and write (hook button events into) the model beneath. These UI classes will probably have so much in common after that.
You can use UnityEvent class for communication between UI and model, they are nicely shown in the Inspector (the same events used in UI Events and Event Triggers).
Fore more general info, Google on some design patterns like MVC, MVP, MVVM, or VIPER.
My recommendation is to strongly consider why you have statics. I understand your reasoning that they are singletons but I don't think that is a good enough reason.
I hope you are using the Unity GUI features properly.
I would just write a base "Menu" component. Then you can add references into the sub classes. For example.
You have a "StartMenu" class derived from "Menu" which is derived from "MonoBehavior". In "StartMenu" you write a method "ShowCharacterCreationMenu()". Then add a button component and hook the method up to that button press. StartMenu will have to have a reference to Character menu. This is the classical OOP approach.
I would do this a little differently though. Unity's strength lies in component based design so I would lean towards that. I would probably create a "Transition" component class that listens for a button press. When that button is pressed it goes to the next menu.
Hope that makes some sense.
https://github.com/brianchance/MvvmCross-UserInteraction is a very nice plugin for showing cross platform Alerts!
But for this question, can we assume it can not use a UIAlertView (or some other top level MessageBox type call on other platforms) but needs to show a Message within a given subsection of the screen (i.e. on IPhone you would need to supply a UIView to the plugin which it will use to show the message within).
So, how would you set this up so the ViewModel knows what View to use as its display container?
As a specific example, if I wanted an Error Service, as so -
public interface IErrorPFService
{
void Show();
void Hide();
void SetErrors(List<Error> errors);
}
and I create a platform specific implementation for it.
If I inject this into my ViewModel so it can control Error Show/Hide/Set how do I tell it the UIView (or equivalent) that I want my Errors to show within?
Can I just expose the IErrorPFService field as a public property and do -
MyViewModel.ErrorPFService = new ErrorPFService(View);
in my ViewDidLoad ...
Or is this coupled incorrectly vs Mvvm Practice?
I would expect the ViewModel to subscribe itself to the ErrorService.
When receiving a message it would expose it in a collection(?) and the View would bind to that collection.
This way the View is unknown to the service and the ViewModel has the chance to influence the View contrary to your solution.
It would help if you could give an example for the scenario you are describing.
Sometimes, the way you visually want to display something might not be the best way, so if it's possible for you, you might find a different and simpler way, which spares you from having to find a solution regarding what you are describing.
Generally, I always do the best I can to avoid the idea of having to actually pass a 'view' or an abstraction of it, from the view-model to view. Also, cross-platform wise, things can work very different in terms of UI interaction. You can find yourself in a situation when things are complicated just because UI works differently than what you expected.
But let's try find another perspective:
At any given point, the view knows what data \ feature it's displaying. So when you are calling from the view-model an user interaction action (by a service, property change, event, etc) the view should 'expect' it.
For example, the platform specific user interaction implementation is able to get the currently displayed top-view and interact it in a platform specific manner or based a relationship. In your example, the message-box can be displayed in a specific sub-view of the top level view.
In advanced scenarios, I guess you could try to create a cross-platform approach for this, but you should try to put in balance all the abstraction you want to create just for that. Think about doing this as a plan ... Z. If possible. Again, giving an example might help.
I'm new to RCP and I'm trying to create a new View or Editor. At the current state I'm extending ViewPart.
The Layout I want to achieve is a SashForm where both sides have a CTabFolder. One of the sides of the SashForm is basically a MultiPageEditorPart. One of it's tabs should be an editor for a specific language with syntax highlighting and similar features. From what I understand I could extend AbstractTextEditor for that (and maybe use it as one tab of a MultiPageEditorPart).
If I try to achieve this layout with a ViewPart as top level container which contains a SashForm, I can't add an EditorPart to one of the sides of the SashForm. Of course I could implement this editor from scratch as Composite but I want to avoid that.
I am also willing to use an EditorPart or MultiPageEditorPart as top level container but then I'd have to find a way to get the SashForm layout working. The whole editor should be splited first and then each side should have tabs.
Does anyone have an idea how to solve this?
If anything is unclear please ask. I've got the feeling I've put this into words a little complicatedly.
I think you should just make a ViewPart that has a text editing component of some kind on the left, instead of trying to find a way to use an EditorPart. All that EditorPart is really buying you is dirty flag management and Save support; syntax highlight and so forth you can add to the text editing component yourself (I was surprised at how few drop-in text components I found while poking around the internet just now; I expected to find "a few" and instead I found "basically none").
You can see one way to do very rudimentary syntax highlighting with a StyledText component here: JavaSourceCodeViewer
To see a more robust implementation of things like syntax highlight and autocomplete, take a look at the class that Eclipse uses for the editing of Java source code: CompilationUnitEditor
I think what you are trying to achieve is quite complicated and might require a lot of extra work. See an editor is not just different controls laid out in some order, but it has a lot of additional features that any editor class expects to work. These include things like selection service and action bars etc, that you will need to hook in to ensure smooth running.
That said, it should be possible to achieve what you are hoping for. You can have a look at the source code of the MultiPageEditorPart itself to see how it converts a single editor into a multi page editor, which is capable of hosting a completely independent editor on each of its pages. You would need to achieve something similar if you want your editor to host two MultiPageEditorParts separated by a sash. If you want to carry on, you should start implementing some stuff and if you run into any problems, post them here. You would be able to get a lot better help then.
You need something like MultiPageEditorSite. Use it for inspiration when implementing an EditorSiteDelegate. MultiPageEditorSite has support for separate keybindings between the pages, for example.
class ChildEditorSite implements IEditorSite {
IEditorSite parent;
public Object method() {
return parent.method();
}
}
Using this class, you can easily do the following in your main EditorPart:
class MyCoolPart extends EditorPart {
public void createControl(Composite parent) {
EditorPart child1 = new MyChild();
child1.init(new ChildEditorSite(getEditorSite()), myInput);
EditorPart child2 = new MyChild();
child2.init(new ChildEditorSite(getEditorSite()), myInput);
child1.createPartControl(parent);
child2.createPartControl(parent);
}
}
Be sure to also dispose of your children correctly when you dispose of your MyCoolPart. Please note that this only works in the most basic of cases. An EditorPart that is a DocumentEditor or that relies on IPersistablePart or implements listeners/adapters for confirming a save is probably going to require a lot more Lifecycle management...
With MVP, you normally bind the View (UI) with the Presenter in the Presenter. However with the latest version of GWT, especially with UIBinding, you can do the following in the View:
#UiHandler("loginButton")
void onAboutClicked(ClickEvent event)
{
// my login code
}
Which basically exchanges a lot of anonymous inner class code for some quick annotation code. Very nice!! The problem is that this code is in the view and not the presenter...
So I thought maybe:
#UiHandler("loginButton")
void onAboutClicked(ClickEvent event)
{
myPresenter.onAboutClicked(...);
}
But there are several problems with this approach. The most important, you blur the lines between View and Presenter. Who does which binding, in some cases it's the View, in others it's the presenter (binding to events not in your current view but that need to be attached - for example a system wide update event).
You still get the benefit of being able to unit test your presenter, but at what cost. The responsibilities are messy now. For example the binding is sometimes in the View and others times in the Presenter level. I can see the code falling into all kinds of chaos with time.
I also thought of extending the Presenter to the View, so that you could do this in the View. The problem here is that you lose the Presenter's ability to run standard unit tests! That's a major issue. That and the lines again become blurred.
So my question, does anyone have a good method of taking advantage of the annotation from UIBinding within the MVP pattern without blurring the lines and losing the advantages of the MVP pattern?
I tend to use the #UiHandler approach only when the Handler does view-specific stuff, like adding style names, etc. For other purposes (adding validation, etc), I stick with the old approach of adding the appropriate Handlers in the Presenter.
I'd recommend reading through one of the many threads on GWT Google Group about MVP and UiBinder, such as this one.
To be honest I don't use the #UiHandler annotation much, because as you said, it starts to muddy the lines between the View and the Presenter. It's totally fine to use, and a great shortcut if you don't particularly care about sticking to the pattern, though.
The presenter.onAboutClicked() route is definitely an option, but then you might as well define the handler in the presenter in the first place.
or if you are looking for a real implementation on how to make it work check out this blog post, I have to say that up until I found it everything else was still noise in my learning.
gwt 2.0.x is a great improvement on gwt 1.x but I still believe google has some way to go with their documentation and guidance since as we have seen with uibinder and mvp, it leaves a lot to the imagination on how to make things work.
hope the link shades a little bit more light on what u need.
If using the MVP pattern, your SomeView interface should have an inner Presenter interface defined which in turn in implemented by your presenter (Activity class). So inside the view do the following:
interface SomeView extends IsWidget
public interface Presenter{
...all the methods
public void doSomeAction(SomeView view);
}
...view methods
}
now in the SomeViewImpl class, attach a handler
#UiHandler("some_button")
void onClickSomeButton(ClickEvent e){
// call the presenter method (you have access to it in the ViewImpl class
presenter.doSomeAction(this);
}
It looks a bit long, but the pattern works great.
It's often useful for the view to delegate some of its actions to the presenter using a pattern sometimes referred to as a "supervising controller".
This has also been advocated by Google as a good way to benefit from the nice #UiHandler annotation at your disposal when you use !UiBinder. The main difference with the original presenter pattern is that the view keeps a link back to the presenter in order to invoke some of its methods, instead of the presenter registering callbacks towards the view.
https://github.com/ArcBees/GWTP/wiki/UiHandlers
first post don't hurt me :)
I am using a BorderLayout with the usual North, West, Center, South Panels. On the West ContentPanel, I've got a Tree. If an event (OnClick)occurs I want a particular dialog box displayed on the Center ContentPanel.
What is the best way for me to do this? Currently I'm using a function called returnPanel() that returns the center ContentPanel. In the event handler I call this function (MainWindow.returnPanel().add(myDialog)).
The way you are doing it is intuitive and works, but will start causing hell when the application grows, because different parts of the application are strongly coupled. The solutions to this problems are the MVC design pattern and the observer design pattern.
Ideally, using the MVC pattern, you don't want any widget to 'know' of any other widget. There is only class that knows all the widgets, which is the Controller. Anytime one widget needs to message/signal another widget, it tells it to the Controller class, which relays the message in the appropriate way to the appropriate widget. In this way, the two widgets are decpoupled and one can change without breaking the other. You may want to use an enum to enumerate all possible actions to which the controller has to responsd.
If your widget has to call only the Controller when an event occurs, you may simply call an aptly named (static) method on it and be done with it. However, as soon as multiple other classes needs to be informed of an event, you are better of using the Observer pattern, which allows you to signal multiple other classes, without changing your class. It simply calls notifyPObservers() in the eventHandler and that's it. How many listeners there are, and what type they are, is irrelevant. This way, you also decouple a class from it's listeners. Even if only the Controller listens, it may be advisable to use the pattern, as it clearly seperated the 'call back' code from the other code in the classes.
BTW, this has nothing to do with GWT or even Java in particular.