Implementing "Expand/Collapse all" with DisclosurePanels in GWT - gwt

I have a lot of DisclosurePanels nested one inside another (or may not be nested either). I want to implement "expand all" and "collapse all" buttons.
Please suggest a clean way to do so.
Note: I tried looking a bit onto Event handling in GWT but got a bit confused with things. I am not sure if I could use Custom Events for my case. It seems that I can define a custom event and its handler and do the addHandler() stuff but in the class that'll implement the handler interface I don't have the instance of DisclosurePanel that'll allow me to use setOpen() property of disclosure panel.

One way of doing this would be to introspect the Widget hierarchy. Starting from the topmost parent disclosure panel, look at all of the child widgets, check if they are DisclosurePanels, and either open/close them. This could be potentially bad for performance if there are many widgets, but you could try anyways.
This code hasn't been tested, but might do what you need:
void openChildren(Widget w, boolean isOpen){
if(w instanceof DisclosurePanel){
((DisclosurePanel)w).setOpen(isOpen);
}
if(w instanceof HasWidgets){
for(Widget ch : ((HasWidgets)w)){
openChildren(ch, isOpen);
}
}
if(w instanceof HasOneWidget){
openChildren(((HasOneWidget)w).getWidget(), isOpen);
}
}

Related

Overview of Handler in GWT

Is there an overview about all handlers and their corresponding containers in GWT? Whenever I try to add a handler to a container, I have to check, whether the handler fires an event or not (the JavaDoc does not provide useful information about this). For example a ResizeHandler:
SplitLayoutPanel splitLayoutPanel = new SplitLayoutPanel() {
#Override
public void onResize() {
super.onResize();
System.out.println("onResize");
}
};
splitLayoutPanel.addHandler(new ResizeHandler() {
#Override
public void onResize(ResizeEvent event) {
System.out.println("resize");
}
}, ResizeEvent.getType());
Overwriting the onResize()-method (1. example) gives an information, if the splitter changes, but if I add a ResizeHandler (2. example), I do not get any call of the onResize-method. I don't understand why and don't find the documentation why the handler is not allowed in this container.
I search for an overview of all available handlers, together with their possible containers and event, when they will be fired.
Usually there will be a more specific addHandler method. For example, Button has addClickHandler(ClickHandler). The interface that defines that method is HasClickHandlers, so you can look out for that, for example.
If the event doesn't have it's own addXyzHandler method, it probably won't be supported very well. In that case, it's usually pretty easy to subclass the widget and add support for that handler yourself.
If you add a handler using addHandler() on a Widget, you have to ensure the underlying DOM element could catch matching event. If yes, you also have to tell your Widget to sink this event using
void com.google.gwt.user.client.ui.Widget.sinkEvents(int eventBitsToAdd)
where eventBitsToAdd is a constant from com.google.gwt.user.client.Event.
AFAIK ONRESIZE event is not yet supported natively. So as I said yesterday, you have to implement your mouse handlers and gesture, or override a slider ;-)

Using layouts from others classes in vaadin

Is there any idea wich allows me using layouts declared in MyApplication.java from other classes and functions.
I tried put them in parameters it works but it becomes very complicated
For example xhen callin a function named Y in function X I have to pass all layouts on parameters like this:
X(layout1,layout2,layout3,layout4)
{
Y(a,b,c,layout1,layout2,layout3,layout4)
}
I tried to use a class named uiHelper but it didn't works
You can take a look at Blackboard addon for vaadin.
https://vaadin.com/addon/blackboard
From that page:
Sometimes, having a deep component hierarchy poses a problem, when you need to inform a component high up in the tree that something happened deep down below. You normally have one of two choices - either pass the listener all the way down the hierarchy, leading to more coupled code, or let each component in between be a listener/notifier, passing the event all the way back up. With the Blackboard, you can register any listener to listen for any event, and when that event is fired, all the listeners for that event are triggered. This keeps your components clean and rid of unnecessary boilerplate code.
For your example, you can create a LayoutChangeListener and LayoutChangeEvent.
MyApplication can then implements LayoutChangeListener and when a LayoutChangeEvent is fired, you can change your layout without passing it around.

Static methods & inheritance in Coffeescript

I've been reading up a bit about coffeescript's inheritance model and I have the feeling I'm on the fringes of an ideological debate which I really don't understand. So, I would be perfectly happy to find out that I'm just doing things in the wrong way.
Basically what I am doing is writing a set of widgets which, among other things, need to handle events on their DOM elements. I thought a good way to go about this would be to have a class method which would be called once, to delegate all the events which the widget might need. The base widget class might have some simple click handlers, while the subclass might add to that some mouseover handlers or extra click handlers.
However, it appears that I'm not supposed to try and do the equivalent of calling super() inside a static method. There is a workaround which exists, (this.__super__.constructor.METHODNAME() but I've seen a lot of suggestions that this isn't the best way to do what I'm trying to do. Has anyone got any insights on how I should structure this code? Keep using the workaround, or put all the delegation into a totally different place? I can't really just stick it in the prototype, since I won't necessarily have an instance to call the method on (or can I essentially still call a method on the prototype from a static context, like putting SwatchableWidget.prototype.delegateEvents() into an onload function or something?
Here's a bit of code to illustrate what I'm talking about:
class Widget
#testProp: "ThemeWidget"
#delegateEvents: ->
console.log "delegate some generic events"
class SwatchableWidget extends Widget
#testProp2 = "SwatchWidget"
#delegateEvents: ->
console.log "delegate some specific swatchable widget events"
this.__super__.constructor.delegateEvents()
Widget.delegateEvents()
SwatchableWidget.delegateEvents()
Thanks for any help.
I suggest replacing
this.__super__.constructor.delegateEvents()
with
Widget.delegateEvents()
trying to use super to call static methods is not required (and doesn't make much sense)
I don't understand why delegateEvents would be a class-level method, or why Widget.delegateEvents have to be called again from SwatchableWidget.delegateEvents. If it's just class initialization code, you should put it in the class body directly:
class Widget
console.log "delegate some generic events"
...
#testProp: "ThemeWidget"
class SwatchableWidget extends Widget
console.log "delegate some specific swatchable widget events"
...
#testProp2 = "SwatchWidget"
I take it you're waiting for a specific DOM state before running this initialization code? Maybe I could suggest another approach if you told me a little bit more about the preconditions for delegateEvents.
It sounds like you want a different type of inheritance model where each inherited function of a certain type ("parent calling") will walk the inheritance tree and call all its parents with the same name.
You could call any direct parent functions in each child manually as you've written. Then it will float up the inheritance chain anywhere you specify such a relationship.
I would bind the parents delegate call in the constructor to a current class function
delegateparents =>
#call any parent class methods

how to keep view "humble" -using SuggestBox with special Oracle and Suggestion

i learned how to implement my own SuggestionOracle("AuSuggestOracle") and own
Suggestions("AuMultiWordSuggestion"). In my case the suggestion object
is constructed with a DTO. On a selection event i need this dto (or
some fields of it) to react appropriate.
I implemented a widget containing 3 suggest boxes with this special
oracle and some logic between them. Now i want to apply MVP pattern -
split this widget in presenter and view.
At the moment the presenters display interface look like that:
public interface Display {
HasSelectionHandlers<Suggestion> getFedLand();
HasSelectionHandlers<Suggestion> getCounty();
HasSelectionHandlers<Suggestion> getCommunity();
AuSuggestOracle getFedLandOracle();
AuSuggestOracle getCountyOracle();
AuSuggestOracle getCommunityOracle();
void clearCounty();
void clearCommunity();
void activateForm();
Widget asWidget();
}
the problem is the implicit knowledge about my model in methods
returning "AuSuggestOracle". so my question is how to get the view/
interface "humble". in my case the displayed suggestion-strings are
ambiguous and i need at least the "id" of a selected item to know what
DTObject is selected.
The way I got around this is by leaving out the getters for the Oracle since once my presenter sets it my view doesn't need any information about it. So, my interface looked like this:
public interface Display {
...
void setSuggestionOracle(SuggestOracle oracle);
HasSelectionHandlers<SuggestOracle.Suggestion> getSelectionListener();
}
The problem I encountered was being able to add the suggestion to the SuggestBox after it was instantiated. To get around this, I initialized with a blank SuggestBox and then removed it from the view, updated in, and inserted it back into position.
After that, you can write your handler (in the presenter) to check if the suggestion is an instance of your custom suggestion and your presenter can handle the selection and push the relevant information back down to your view.
By doing this, all your view knows is that it will be taking generic suggestions for something, and that at some later time it will be updating with information (which will be as a result of the suggestion, but the view is to 'humble' to know that).

How do I add ScrolledWindow support to a custom Widget in GtkMM?

I am writing a custom widget for Gtkmm that is supposed to display a huge dataset (imagine something like a 4096x256 character datasheet).
Mostly for reasons of elegance, but also for a possible usage in a Glade/Gtk-Builder editor, I want this widget to support ScrolledWindow natively, that is, once it is set as the child of ScrolledWindow, it is recognized as a scrollable widget, allowing to set horizontal and vertical Adjustment objects on it, which it can subsequently tamper with.
It appears to do so, I need to do something like this in the constructor of my widget:
// get Gtk C type from wrapper class
GtkWidget* gwidget = this->gobj();
// imagine code here that magically creates a gobject signal,
// that we can catch in C++.
// this is actually the part which I don't know how to do.
guint my_signal = magic_way_to_create_this_signal(
&MyClass::rainbow_unicorn_signal_handler);
// make ScrolledWindow recognize this window as scrollable
GTK_WIDGET_GET_CLASS(gwidget)->set_scroll_adjustments_signal = my_signal;
Later on, the signal emitted by ScrolledWindow when the widget is added needs to be caught by my Widget through a signal proxy method or something? I have no idea.
How can I do this?
The 'magic_way_to_create_this_signal' is g_signal_new(). You call it in your widget's my_widget_class_init() function which is part of the GObject way of defining a class. I'm not exactly sure what the equivalent is in Gtkmm.
See also the footnote in the GTK docs, where it is explained why making a widget natively scrollable is such a hassle.
You could also put your widget into a Gtk::Viewport which adds scrolling capabilities to its child widget.