GWT DeckLayoutPanel sliding to a NEW (not-rendered-yet) widget? Doesn't work - gwt

I can't seem to slide to a new, not-rendered-yet widget added to a DeckLayoutPanel, no matter what I try.
It appears without the slide transition if it's never been rendered before.
However, when I do showWidget(...) back and forward to the new widget, then the slide transition works fine.
Has anybody been able to slide to a not-rendered-yet widget in DeckLayoutPanel? If so how?
I need this functionality.

You can use the scheduleDeferred comand. This will make sure that your slide command is executed, when the widget is actually shown.
It defers some code until after the browser redraws the page (if needed) and pending events are processed (that is after the mouseup and click if this is done in mousedown)
Source
Docu
Usage:
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
#Override
public void execute() {
Scheduler.get().scheduleDeferred(/*Your silider comand*/); // reschedule
}
});

Related

Set focus to an Input in a gwtbootstrap3 Modal

I want to set the focus to a certain field (org.gwtbootstrap3.client.ui.Input) in a dialog (org.gwtbootstrap3.client.ui.Modal) before the dialog shows up. The use case seem quite common, if you have a dialog with a single field like the Upload text or Add feed dialogs right here. However I could not figure out how to set the focus to this particular gwtbootstrap3 component.
The Input component does have a setFocus(true) method. I assumed that setting the focus before showing the dialog would not work, which it doesn't. So the logical solution is to put the method call inside a ScheduledCommand. Like this:
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
#Override
public void execute() {
textField.setFocus(true);
}
});
That usually works with GWT standard components, but does not seem to help in this case. I found a way to get notified once the dialog is shown through a ModalShowHandler. Like this:
modal.addShowHandler(new ModalShowHandler() {
#Override
public void onShow(ModalShowEvent evt) {
textField.setFocus(true);
}
});
I even tried to combine both, adding a deferred call to the handle. No luck. Any ideas?
You should be listening on the ModalShownEvent (note: Shown, not Show).
ModalShowEvent is fired when the modal is requested (for example, programmatically) to be shown.
ModalShownEvent is fired when the modal is actually shown.
This somewhat confusing naming is based on the events of the native Bootstrap Modal's events: show.bs.modal and shown.bs.modal.
ModalShownEvent combined with the usual Scheduler#scheduleDeferred should do the trick.

MTextBox setFocus() not showing the focus on textfield on view load, MGWT

I built an app with gwt,mgwt and gwtphonegap. One of my view having few text fields, I have a requirement that I need to set the default focus on my first field
when I visited that view. For this ,
firstInputField = new MTextBox();
firstInputField.setFocus(true);
//I'm not calling setFocus() on remaining fields.
But my firstInputField not having focus when view is loaded. If there are any straight or alternative ways to do it,please provide me.
thanks in advance,
Arun Kumar.
The Box should be added to the DOM, if you only create a box, without any context to the Browser HTML, it can not handle the focus.
Add the Box in your view and set your Focus, if it is not working, try to wrap the setFocus in a Scheduled Command:
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
#Override
public void execute()
{
firstInputField.setFocus(true);
}
});
The ScheduledCommand will be fired, after the renderloop is done, and all html elements are ready, and a focus can be set.

Remove the focus from whatever has it

I am handling MouseDownEvent and MouseUpEvent on an Image, in order to allow selection of part of the image. Most browsers will start dragging the image around unless preventDefault() is called on the event, as is visible on this image:
The major downside of calling preventDefault() is that if the focus was on, say, a TextBox, it will remain there, even though the click on the Image should have removed it.
I couldn't find a way to remove the focus from whatever widget currently happens to have it, or to give the focus to the Image. My only workaround so far is to create a useless TextBox that is not visible, and when I want to remove the focus I make it visible, give it the focus, and make it invisible again. Yuck. Any better suggestions?
In order to make the image focusable you have to add the attribute tabindex to the element, then you can call the Element.focus() method to put the focus on the image when the user clicks on it.
final Image i = new Image("http:...");
i.getElement().setAttribute("tabindex", "0");
i.addMouseDownHandler(new MouseDownHandler() {
public void onMouseDown(MouseDownEvent event) {
event.preventDefault();
i.getElement().focus();
}
});
Another way if you dont need the image focusable, is just handling the dragStart event and prevent the default here instead of in the mouse down and up handlers.
i.addDragStartHandler(new DragStartHandler() {
public void onDragStart(DragStartEvent event) {
event.preventDefault();
}
});

Is there a way to tell when a Widget is shown with GWT?

I'd like to respond to an even whenever my widget is made visible on a page done with GWT and UI Binder.
Is there anything similar to the onAttach() event handler (which fires when the widget is added to the DOM), pertaining to when the widget is actually made visible?
I'd like to be able to handle the even when the widget is shown because there are a few different ways of making it visible, and I'd like a single place on the widget itself that can handle this event.
Thanks
I know this is an old question, I have faced the same problem before. What I did was override the setVisible(boolean visible) method in the widget, then perform whatever I needed to do:
#Override
public void setVisible(boolean isVisible) {
super.setVisible(isVisible);
if(isVisible) {
// Do whatever you need to do with your widget
}
}
The widget should be visible once added to the DOM unless you've intentionally hidden it (i.e. with CSS or hid it behind another widget). Normally, onAttached() means its on the page. If you're using CSS classes to make it visible, write a setVisible(boolean isVisible) method to your widget and set the visibility class this way. If you have it behind another widget (i.e. in layers) then you'll need to write your only logic to determine when it's visible.
There is no browser event for this, but you could try this:
With your widget you could check the elements getLeftOffset (or similar method), if you get a positive value, you could fire your method, and set a flag to indicate that your onVisible() method had fired.
Then once the getLeftOffset returns a 0 you could reset your flag, ready to fire your event again.

Get the GWT ScrollPanel to start its vertical scrollbar at the bottom

I know there are some questions out there about the GWT ScrollPanel and how it works, but allow me to explain the situation.
I'm working on a project to implement QoS on routers. I'm now at the developping stage of the project and I need to make a webinterface to add protocols such as ssh and http and give them their bandwidth.
To save memory usage and network traffic, I do not use GWT-EXT or Smart GWT. So to set the bandwidths I use a ScrollPanel with an empty SimplePanel in it (which is way too big), leaving only the scrollbar.
Now here's the problem:
I want each scrollbar for each added protocol to start at the bottom, not the top. I can get it working through the code if I manually move the scrollbar first, then any function works, like a scrollToBottom(), or a setScrollPosition(). If I want to move scrollbars through code before moving the scrollbar manually, however, I can't call a function on it.
(I would post a picture but I can't yet - new user)
Summary:
So if I add a protocol (using a button called btnAjouter), the two slidebars (One for guaranteed bandwidth and one for the maximum bandwidth) for each protocol start at the top. I want them to start at the bottom on the load of the widget.
Is there a way to do this?
Thanks in advance!
Glenn
Okay, my colleage found the solution. It's a rather dirty one, though.
The thing is, the functions only work when the element in question is attached to the DOM. I did do a check with a Window.alert() to see if it was attached, and it was. But the prolem was that the functions were called to early, for example on a buttonclick it would've worked. The creation and attachment of the elements all happens very fast, so the Javascript can't keep up, this is the solution:
Timer t1 = new Timer()
{
#Override
public void run()
{
s1.getScroll().scrollToBottom();
s2.getScroll().scrollToBottom();
}
};
t1.schedule(20);
Using a timer isn't the most clean solution around, but it works. s1 and s2 are my custom slidebars, getScroll() gets the ScrollPanel attached to it.
You can extend ScrollPanel and override the onLoad method. This method is called immediately after a widget becomes attached to the browser's document.
#Override
protected void onLoad() {
scrollToBottom();
}
Could you attach a handler to listen to the add event and inside that handler do something like this:
panel.getElement().setScrollTop(panel.getElement().getScrollHeight());
"panel" is the panel that you add your protocol to. It doesn't have to be a ScrollPanel. An HTMLPanel will work.
You can wrap this method in a command and pass it to Schedule.scheduleDeferred if it needs to be called after the browser event loop returns:
Schedule.scheduleDeferred(new Scheduler.ScheduledCommand(
public void execute() {
panel.getElement().setScrollTop(panel.getElement().getScrollHeight());
}
));