GWT Activities and Places - How to understand this concept? - java

Okay, Activities build on top of Places. Places are "just URLs". But I am just not getting it how to use them properly..
There are no nested Activities "because YAGNI"; but how does it look like in this simple scenario:
Having a login page
Having an administration page that offers functionallity for
Add events to my company
Add items to my store
After a successful login the "main container" of the website is cleared and filled with the new content of the admin-activity. One thing that has to be changed here is the "display" of the ActivityMapper since now I got a navigation bar on the left side and a main-content Div on the right side.
I could just have a LoginActivity and an AdminActivity. That means I'd have urls like
/#LoginPlace:noParams
/#AdminPlace:eventManager
/#AdminPlace:itemManager
But that's silly imho because for real I would like to have something like this:
/#LoginPlace:noParams
/#AdminPlace:eventManager|storeId=1,langaugeId=2
/#AdminPlace:itemManager|storeId=1,langaugeId=2,page=0
But that would require my AdminActivity to break up the URL and look out for all this different types of URLs, right? What I mean is something like this:
private AdministrationActivity administrationActivity;
#Override
public Activity getActivity(Place place) {
if (place instanceof LoginPlace) {
return new LoginActivity((LoginPlace) place);
} else if (place instanceof AdministrationPlace) {
if(this.adminActivity== null) {
this.adminActivity= new AdministrationActivity((AdministrationPlace) place);
} else {
this.adminActivity.updateMainContent(((AdministrationPlace) place).getUrl());
}
return this.adminActivity;
}
return null;
}
Where now adminActivity.updateMainContent() will have to do the parsing for all places in order to display the correct content.
This would be the solution:
/#LoginPlace:noParams
/#EventManagerPlace:storeId=1,langaugeId=2
/#ItemManagerPlace:storeId=1,langaugeId=2,page=0
But(!) now I need an activity for each place, right? And I am just not sure if there are equally as many places as there are activities. I thought that one activity can navigate to different places.
So how are Places and Activities supposed to used?

The first questions you have to ask yourself is "where will the user possibly go?". As I understand it, you at a minimum have:
list of events, with possible filter/selection criteria and paging attributes
list of items, with possible filter/selection criteria and paging attributes
Maybe you'll also have places like "details of an event" (maybe even split between read-only details and editable details, if the user will switch between both states; if the state depends on who the user is, then this is IMO the same place, and actions the user can do are different), "details of an item", "form to add an event", "form to add an item".
To me, login is a cross-cutting feature, it's not something the user comes to doing in your app (it's not a business use-case, not an "activity" that's part of the user's job). You can still choose to use a place and activity for login though; so let's add that to the list: "login form" (definitely not how I'd do it, but that's another story).
Now you can choose how you want to represent those places as GWT Place objects: you can have one Place subclass with a property telling you which exact "place" you're on (basically what your AdminPlace:eventManager token suggests), or one Place subclass per "place" (what your EventManagerPlace token suggests). This is entirely independent of whether you'll have one or several activities.
The next question is about the various areas of the screen, that'll map to ActivityManagers: what parts of the screen do change when navigating? Maybe they do not all change at the same time / under the same conditions.
So for example, should your navigation bar be within the activity or not? If you can put it outside (because it's reused), do it. It actually need not even be an activity if it's always the same (modulo the selected item). In any case, it's probably a good idea to make it a singleton (or similar) and listening to PlaceChangeEvents to select the appropriate item (not necessarily a "singleton", but at least not recreated on each navigation). The advantage of putting the navigation bar outside the activities is that if you finally decide to have it vertical rather than horizontal (or the other way around), and/or collapsible, you won't have to change your activities (separation of concern). If you ever have to build a mobile app, you could even have a "menu" place on that app that displays the navigation bar full-page and swaps it for the other activities when navigating.
So we now have 2 display regions, i.e. 2 ActivityManagers, and their respective ActivityMappers. Or maybe just one display region for the "main content", and the navigation bar is not an Activity. The next step is to determine exactly what changes and when; i.e. when I go to place X, I need to have that thing in that area, and that other thing in that one; those "things" are your activities.
The key to "model" your Activities is to think about the things the user does (activities) and focus on one of them. But Activities are also tied to how the user interacts with the application, and the navigation (e.g. when adding an item, does the form appears in a popup above the list, or replaces the list); so if you want to really completely separate concerns, you'd probably create some object to manage the list of events/items and have a really thin Activity that only instantiates and manages that object. That's probably over-engineered as a starting point though, and it'll be relatively easy to factor the thing out of the Activity later if you feel it's needed.
I like (and that's basically how the feature has been designed) to have disposable activities. In my ActivityMapper, everything from the Place that the Activity needs to know is passed to its constructor; the Activity doesn't have to know the current place (or listen to place changes), and is not "mutated" by the ActivityMapper. There can of course be exceptions to the rule, for various reasons. If you need to share state between "places" for a given activity (e.g. data caches, etc.), you don't necessarily have to reuse it, you can share the state via shared stateful objects and keep the activity mostly stateless.
Anyway, your idea of a big AdminActivity that itself swaps a big part of its content depending on the current place is akin to nesting.
In the end, there's no one-size-fits-all, and you'll have to try and pick the strategy⋅ies that best fit your needs.
Last, but not least, don't design your place with a generic getUrl() that needs to be parsed; parse everything in your PlaceTokenizers; nothing else than the tokenizers need to know how the place will look like in your URL (and you're not even forced to use a PlaceHistoryHandler to begin with, so your places might not even ever end up in the URL –your places won't be bookmarkable then and you won't be able to navigate in the app through the browser history)
The key concept is separation of concerns.

I'd suggest you probably do want one Activity per Place. There is generally a rough one to one relationship but they are split due to separation of concerns and so you can pass around a Place without an Activity.
Adding parameters is sadly not supported by standard GWT. We created our own simple one based on UrlBuilder.
There is a long standing issue for this https://code.google.com/p/google-web-toolkit/issues/detail?id=2422 (old issue tracker) which has other thoughts and links.
Once it is up and running it works really nicely. I like using strongly typed objects and goTo rather than sticking URLs together.

Related

How to model parent-child relationship in Android MVVM VMs?

I'm working on an Android piano "quiz" app - users tap on the piano keys and then click the yellow "check" button to submit the answer for evaluation and see the correct answer drawn on the piano. The main QuizActivity has this layout:
The upper part of the screen hosts a couple of controls (Text, submit buttons, etc.).
The lower part of the screen is occupied by a custom PianoView component, that handles drawing of the piano keyboard.
According to the MVVM principles, the PianoView should have its own PianoViewModel, that stores its state (i.e. currently pressed keys, highlighted keys, etc...) in a KeysStateRepository.
The enclosing QuizActivity should also have a QuizActivityViewModel, that handles the various controls (submitting an answer, skipping a question...).
The QuizActivityViewModel needs to be able to query the selected keys from the PianoView (or rather from its KeysStateRepository), submit them to the Domain layer for evaluation and then send the results back to the PianoView for visualization.
In other words, the QuizActivity's ViewModel should own/be a parent of the PianoView's ViewModel to facilitate communication and data sharing.
How can I model this parent-child relationship to communicate between the ViewModels?
AFAIK a ViewModel cannot depend on another ViewModel (What would I pass as the ViewModelStoreOwner to obtain a ViewModel in another Viewmodel?). I don't think it's possible to achieve with Dagger-Hilt at least.
Three solutions to work around this problem came to mind, all of them unusable:
1 - The official way of sharing data between Views
The Android dev docs recommend using a shared ViewModel to facilitate sharing of data between two Fragments / Views. However, this does not fit my use-case. The PianoView (or its ViewModel) should be the sole owner of its state with a Repository scoped to its ViewModel. Otherwise, the PianoView component would not be reusable. Consider for example another Activity, where I'd like to have two independent PianoView instances visible:
Reusing a Shared ViewModel from the quiz activity would be obviously wrong, because it contains irrelevant methods and logic (i.e. submitting quiz answers) and would not fit the two-keyboard scenario.
2 - Application-scoped repository
A similar problem was tackled on Reddit with a proposed solution of using a shared instance of the repository. However, using a #Singleton KeyStateRepository would once again prevent the two independent keyboards to display different data.
3(EDIT) - 2 duplicate repositories replicated by an Event Bus
I could in theory create 2 independent ViewModels and 2 KeyStateRepository instances. The ViewModels would subscribe to an event bus. Each time a ViewModel invokes a mutable operation on its repository, it would also fire an event and the operation would get replicated via the other ViewModel subscribed to the same event bus.
However, this feels like a fragile & complicated hack. I'd like to have a simple MVVM-compatible solution. I can't believe a simple parent-child relationship for two UI components is something unattainable in MVVM.
I think you got a decent answer from Pavlo up there, I'll just clarify what he meant with other words.
KeyStateRepository is a storage for the state of piano keys. There's nothing stopping you from making it to support N number of Pianos at the same time, this would solve the scenario where you have NNN Pianos on Screen, each with different keys pressed.
The PianoView should be contained in a Fragment, that should be your "unit". Why? Because you want a ViewModel to handle the state and events coming to/from the view. And a Fragment is the Android artifact provided for that regard. Think of it as an annoying piece of baggage you need. Android Devs used to call these things "Policy Delegates" because you delegate to these (a Fragment/Activity) some things you cannot do without "the framework" (the Android Framework, that is).
With this in mind, you have an Activity whose viewModel/State is handled independently. What State/Events do this viewModel handle? Things that are not in the PianoFragment/View(s). E.g. if you wanted to handle the back navigation, or a "record" button at the top, this is the activity's domain. What happens inside the "PianoView/Fragment" is not this activity's problem.
Now the Fragment that will contain the actual PianoView can be designed to contain "more than one" or just one. If you go for more than one, then the PianoContainerFragment will be designed with a ViewModel designed to handle more than one PianoView (so each view will have a "name/key") and the KeyStateRepo will be able to handle the "CRUD" operations of any Piano View you throw at. The ViewModel will sit in between, dispatching events for different "subscribed" views.
If you elect to go for "one fragment contains one piano view", then it's a similar architecture, but now handling the multiple "fragments" in one "activity" is now responsibility of the Activity (and its view model). But remember, the PianoViews (via a Fragment either shared or not) talk to a ViewModel that can be shared among piano views, that talks to a common KeyState Repo. The activity coordinates the views and other Android things (navigation, etc.) but the views operate independently, even of each other.
You don't really need a shared viewModel I think, in fact, I wouldn't do it until really needed, the more you separate things, the less the chances of "violating" one of the fancy patterns... but if you elect to use the PianoViewModel as a shared among all views, that's perfectly acceptable, you're going to have to include the Piano "Name" to differentiate whose events are for whom.
In other words (showing with ONE PianoViewModel for ASCII Simplicity),
// One QuizActivityViewModel, Multiple Fragments:
Activity -> PianoFragment (PianoView)|
| <-> PianoViewModel <-> KeyRepo
PianoFragment (PianoView)| /
-> QuizActivityViewModel <----------------------/
Here the QuizActivity creates N fragments (in a list maybe?). These fragments internally initialize their pianoView and connect to a PianoViewModel (can be shared like in the graph above) or each can have its own. They all talk to the same Repo. The repo is your "single source of truth about what each "piano". What keys are pressed, and anything else you can think of (including a name/key to make it unique).
When QuizActivity needs to evaluate the state of these, it will ask (via its own viewModel) for the state of NN pianos.
Or
// 1 Act. 1 Frag. N Views.
Activity -> PianoFragment (PianoView)|
(PianoView)| <-> PianoViewModel <-> KeyRepo
-> QuizActivityViewModel <---------------------------/
With these, the QuizActivity (which created the pianos to begin with as well), also knows the keys of the pianos that will/are displayed. It can talk to its viewModel that talks to the same KeysRepo (you only have one of these and that's fine). So it can still handle the "nav" buttons and it can ask (via its QuizActVM) what the current state of the Keys are (for all involved pianos). When a Piano key event is fired in a PianoView, the PianoViewModel will receive the event (what key was touched, in what piano); the KeyStateRepo will record this, and perhaps update a flow {} with the events coming from the pianos...
The Flow will be expressed in a sealed class which will contain enough information for both QuizActivity + VM (to perhaps perform a real-time validation), and to the PianoViewModel to update the state and push a new state to the PianoFragment (Which will update the state of its view(s)).
This is all common to either method. I hope this clarifies the sequence.
Does this make sense to you?
Edit
In a multiple architecture activity if you wan't PianoViews to have ViewModels and your ActivityViewModel to know about them - don't use Dagger injection with them but create PianoViewModels inside an ActivityViewModel and assign some callback to them on the stage of creation - thus you will have an access to them and will be able to listen to their events and influence their behaviour as well as save their state, from inside the ActivityViewModel. It is not an uncommon and in some cases even a correct approach. Dagger - is a mere instrument that is not intended to be used everywhere, but only there were it is needed. It is not needed to create PianoViewModels - you can inject all the needed stuff into the ActivityViewModel and pass all the needed elements to PianoViewModels constructors.
Also you don't need to wrap your Views into Fragments if you don't want to.
Edit end
You are making wrong assumptions based on a flawed architectural approach.
I am curious why do you need ActivityViewModel at all. View model should exist only for the elements that have some View. Current android development suggests that the Activity should not have a view representation and serve as a mere container of other views(Single activity principle). Depending on your architecture Activity may handle showing the loading state(progress bar) and some errors, but once again it should not contain anything that is being handled by other views. Thus PianoView should be a PianoFragment with its own ViewModel that handles access to its repository on the data layer via interactor on the domain layer.
The shared view model would work in case you would need one, and you would be using the Single activity principle with multiple fragments. Because Jetpack Navigation has the support of the shared view model out of the box. In the case of a shared view model - each fragment would have its own view model along with a shared one for communication. Each navigation graph could have a separate shared view model only for the fragments it contains.
Also regarding KeyStateRepository - you need only one of those(or a Dagger #Scoped multiple copies - but I do not recommend it). The only change should be - the addition of an extra key for each separate PianoView - to distinguish them inside a KeyStateRepository. To easily achieve that you may be using Room or some other file/memory/database cache mechanism.
Hence the initial problem of your app is not an inverted dependency of ActivityViewModel on a PianoViewModel, but a flawed architecture of the app and its inner interactions. If you want to continue work with your current architecture - there is no easy answer to your question, and almost every chosen solution would not be 'clean' enough to justify its usage.
I would do the following, if you don't want to tie the PianoViewModel to your ActivityViewModel, I'd just create an interface, which the ActivityViewModel implements, and the PianoVM could have a nullable reference to that interface. This way neither the implementation, nor the existence of the component would be required for the PianoViewModel to work.
How you get the ActivityViewModel is another question. Check out by activityViewModels() implementation for fragments, you probably can do the same with by viewModels() passing in the viewModelStore of the activity instead

Android: Creating a new instance of a new activity

I'm confused regarding with some basic android development concepts, my question is not pointing at a particular code, thats why I dont include any.
Let's say that I have an activity inside of which I have a container in which I load a couple fragments (they are multiple instances of the same fragment), now the activity is populated, and inside one fragment I press a button that opens a new activity, it doesn't matter what may happen in that activity, the thing is that when I press a button it should take me back to the previos activity, I know that pressing the back button or using .finish(); will take me back to my already-populated activity, but I want to know, if that is the correct thing to do, or should I finish the activity as soon as i leave to the next one and when I want to go back create a new instance and repopulate it, if so, where should i store the variables?
Let's say that the fragments that I mentioned are "alarms" for an alarm application, and when I create it I call AlarmFragment newAlarm = new AlarmFragment(); and then I add that alarm to an arrayList in my alarms activity (java class) getListOfAlarms().add(getAlarmsAmount(), frag); which remains on the activity that has the fragment container, the question is, are these variables created in the right place? Because I am leaving them inside the activity itself right? What could happen if the activity is destroyed? I've been told that I should create an SQL database for storing those variables. I am not talking about long term saving but variables that I will be using at runtime
Can someone explain me these concepts a little bit? A link to a place where it is explained will be great too.
Your question seems like it has many parts.
In Part 1, this is what I think you are talking about:
1) how you decide to allow the user to get back to the first activity is really up to you. And 2) what you leave in the Back Stack is also up to you and what you want to define for the users' capabilities within your app. For example, if you want them to only be able to use a button that you define inside Activity 2 container, that is fine. However, you are not required to provide a button in Activity 2, and you are certainly allowed to use the Up Action in the App Bar for navigation. If I were you, I would read more about the Tasks and the Back Stack http://developer.android.com/guide/components/tasks-and-back-stack.html
You also mention this idea of having to "finish an Activity" with .finish(). I don't think that is usually necessary, but it is available to you if you want to use it based on what you decide for your app's logic (and what the user should and shouldn't be able to do).
With the Back button, Activity 1 will appear as if just initialized when you get back from Activity 2. Try it out. Also run some Log statements based on the simple diagram I provided and the Lifecycle "callbacks" (put these methods in your Activities and throw a Log statement in each to get a better sense of where you are in the Lifecycle) http://developer.android.com/guide/components/activities.html#Lifecycle
As for Part 2 of your question, I would try/set-up some of the above first, then start to experiment with a single variable to see what happens to it between Activities. There are a lot of "what ifs" to your question. You don't necessarily have to create a DB to store your variables, but that could certainly be an option. Take a look at the Developer Guide for most of the Data Storage options: http://developer.android.com/guide/topics/data/data-storage.html
If you are concerned about losing data when the Activity is destroyed, I might consider creating a database. Read the following for more info on recreating an Activity when you have gone elsewhere and are returning: http://developer.android.com/training/basics/activity-lifecycle/recreating.html In particular Saving Your Activity State: http://developer.android.com/training/basics/activity-lifecycle/recreating.html#SaveState
There's also an SO post on this: Saving Android Activity state using Save Instance State

GWT MVP implementation

I have few gwt mvp design related questions:
Can we use event bus to switch views from one presenter to other via controller using custom event?
If above is true, can the custom event (say changeViewEvent) contain name of next view, on the basis of which controller can take a decision, which presenter to show?
Is it a good design to make views reusable(as a widget) in an application, though i don't agree with this, but will be happy if someone has any thing to mention in favor of this.
PS: all my views make use of custom widgets and there is no gwt specific widgets(buttons, checkbox etc...) in views.
You can do anything you want, but you have to consider the consequences. For example, if you switch views without creating a history event, a user may be thrown out of your app when a user hits a back button expecting to see the previous view.
I very much like the Activities and Places design pattern. It takes care of all of the issues (history handling, bookmarks, tokens, etc.) You can also extend it to add animation effects when switching views on mobile devices - mgwt does that.
I have few gwt mvp design related questions :
Can we use event bus to switch views from one prsenter to other via controller using custom event ?
This is a bad practice, unless you have real good reasons to do that. Since you're changing the view without having an impact on the url, you won't know what is a the state of a view at a choosen moment, you cannot get back to a previous view in an easy way, and finally, people will have difficulties reading the code, since you're out of the "standard".
The only reference for you should be the url, you cannot assume data is loaded neither the applicatio is in a given state: each and any view may be the start of the navigation story for your users, so if you get information from any other source than the Place, you're probably doing wrong, especially if your source is an event. the only special case here is you don't want users to enter your app in a certain view state, so you 'impose' that another url is called before, and restrict the access to the view through an event starting from a given application state
If above is true, can the custom event (say changeViewEvent) contain name of next view, on the basis of which controller can
take a decission, which prsenter to show ?
as said before, you're reinventing the wheel. It's far better to adapt to the existing mechanism that is well thought and covers the majority of cases. You can put a json formatter to tokenize your url while developing so it's not a nightmare to put variables in. And when you're done, create a nicer regular url format
Is it a good design to make views reusable(as a widget) in an application, though i don't agree with this, but will be happy if
someone has any thing to mention in favor of this.
depends on what you call a View. if it's the activitie's view then youm might need that in very few cases, it's better to inherit a basic view and fork its children for each activity (even if the view does nothing, time will show it will evolve differently): this is better since the base view contains what is common without the specifics of each child activity.
Finally if you mean a composition of widgets when you say, a view, then you should definitely reuse them, it will make you obliged to improove your widgets and compositions to be in a constant improvement, this will heop you for the rest of the project, and maybe for other projects

Handling large number of Swing components

I'm doing a favor for an engineer friend by making him a program that helps him with the scheduling of his factory's production. Each type of product is broken down to a set of steps (they share a lot of them, but there are a few differences).
The programming issue:
Each time a new production process is registered I display a number of checkboxes representing the before mentioned steps. He can choose which steps he needs added for this particular product. If he checks a checkbox, two (or more) textfields appear where he can add additional information (starting date, duration, comments, etc...). My problem is that this is a lot of individual components and I am unsure how to handle them. Since I will need to have access to all of them at some point (the checkboxes to see if that step is needed and all the textfields for the data) I was thinking of having them all as fields, but that doesn't feel right...
Another approach could be to make a container class that groups the textfields together with the checkbox. Something like this:
ArrayList<MyComponentGroup> group;
for (MyComponentGroup cg : group) {
if (cg.getCheckBox().isSelected()) {
//access and read the data from all the textfields in this object
}
}
What is the Java programming convention or the most commonly used method to handle this situation?
Here's what I would do when dealing with tons of components and similar requirements:
I would model the relationship between options (available through checkbox selections) and the related data to fill (requirements). This model may already be available for you.
I would attempt to use PropertyEditor instances and map them to model elements.
When the time comes to save or use the data filled by the user, I would just walk the model represented on the screen, grab the associated editors and deal with the value of those editors.
I think that the approach that I described above will give you less work and potentially and it will bring more flexibility for your friend.
You'd only pay the initial cost of getting the components relationships/dependencies in a nice model as well as registering the relevant PropertyEditors for visual editing.
One approach is to consistently give each JComponent a unique name. Use something hierarchical to fit the complex process, like "Whites.Rinsecycle.enableCB". For completeness, store this String as a clientProperty in the JComponent. Then you can use that as a key in a large Map to access all the components.
Maybe not the most "elegant" (I'd tend to go with a hierarchy of JPanels with relevant fields) but for a slightly quick and dirty, moderate sized project this is reasonable.

GUI patterns in Java/GWT - general approach

I'm helping to build a GWT application for a client and rewrote most of the stuff to work better, shorter code, faster, etc. However in all the GUI application I've worked on (not so many really) there comes a flexing point where you just have to put a lot of rules and move logic from the listeners to some common mediator. Then some times this could get an ugly mess so you whatever small think you need to do in the listener.
Let's take an example:
form with 10-20 fields
two exclusive radio control about half of the state of the other fields (enabling, validation, input limits)
three exclusive radio controls control again almost the same fields, but in a different way (affecting calculations, enabling); they are also controlled by the above
4 or so number fields are validated on the fly depending on the previous selections and some real-time data object; they can have upper/lower limits, be enabled/disabled
one drop-down box controls the next 6 or so controls - displaying/hiding them, modifying validators
some checkboxes (shown by the above combo) activate some input fields and also determine their validation algorithm
While everything is up an running, without known bugs, there are a few coding gotchas that really bother me:
code is spread among listeners and some mediator methods.
loading the form with some preset values presents its own challenges: like data objects that might be available or not, data objects that might alter their state and subsequent field behaviour
some fields are having a default value set and this should not be overwritten by automatic filling, but if the data objects are not there (yet) then they will need to be filled eventually when the later become available
form cannot be submitted if any of the fields are not validated
My approach:
identify which fields share a common afair and move code into one place
each radio group shares a single listener implementation between its radios
default form filling is deferred until the live data is available (as much as possible) and as a result it gets called multiple times
each action has a call to a common validator method
the validator runs through all the fields in the form, calls their validators (which highlight all errors) and returns a single boolean
each relevant keypress or mouse action, data change it gets deferred to be called after 250ms from the last call; this means first call just places the validator as a delayed action, subsequent calls reset the timer
Ok, it doesn't make any sense to dwelve into more details but I'm more upset about the fact that there is no clear separation between visual actions (enabling), data actions (setting form field values), field listeners, retrieving form values and live data listeners.
What would be a good approach/pattern (next time maybe) to make sure that MVC get separated and lends itself better to maintenance? I know this is not a typical question but I've read every documentation I could get my hands on and still did not find some helpful answer.
I'd move closer towards MVP than MVC. It's clearly the way Google intends to go, so adopting it will probably mean that you're able to go with the flow rather than fight the current.
How does this affect you? Well, I believe you should accept that a tidier implementation may involve more code: not the 'shorter code' you were hoping for. But, if it's logically structured, efficient code the Google compiler should be able to trim lots out in the compiler optimisation phase.
So, move as much of the logic as you can into the model layer. Test this thoroughly, and verify that the correct level of page reset/tidying happens (all of this can be done with plain JUnit, without any UI). Next, use your Presenter (Activity) to tie the View to the Model: handling the interactions, populating the fields, etc.
you can divide a Huge class in different classes bu dividing the GUI in different JPanels. All the panels are implemented in different classes extending JPanel. Guess that would help you.

Categories