Change defaultModel inside onAfterRender - wicket

I have a Panel and a Image inside this Panel.
In onAfterRender I want to change the defaultModel of the Image.
#Override
protected void onAfterRender() {
super.onAfterRender();
previewImage.setDefaultModel(new Model<String>(newUrl));
}
But this has no effect. The purpose is to display a placeholder and when the Panel is rendered, then change its src

onAfterRender() is a callback executed right after the current Component has been rendered, i.e. it has contributed its part of the final HTML sent to the browser.
It is not very clear what you want to achieve with this placeholder.
In case you want to show a placeholder and then lazily load the real image then you can use AjaxLazyLoadPanel from wicket-extensions. Or you can use JavaScript to replace the placeholder once the image is loaded by the browser (img.addEventListener('load', ...).
onAfterRender() is usually used to render something right after the content/body rendered by this Component, but it cannot be used to change it.

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.

How can I create a GWT button with both image and text?

I'm trying to create a GWT button that includes both an image and text like this:
I can create and set the button image like this:
PushButton button = new PushButton();
button.getUpFace().setImage(new Image(icon));
but if I do this the image disappears:
button.setText("ABC");
How can I keep both? I would prefer not to use the setHtml method because that would create a new HTTP request
EDIT: The problem with calling setHTML() is that it causes the browser to send another HTTP request to the server. This means that when I change the icon the button is blank for a second or two while the browser waits for a response from the server - obviously this not ideal. I'm looking for a way to use the image that is in memory in the form of a ImageResource object. Thanks!
There are lots of ways to achieve this.
Please have a look at below post asked in the same context:
HTML/CSS - Adding an Icon to a button
Adding icons to an button in gwt
GWT Custom Button with Icon above Text
Sample code:
Button button = new Button();
// get image form CSS resource
String url = new Image(Resources.INSTANCE.cut()).getUrl();
// get image from url
String url = "https://cdn3.iconfinder.com/data/icons/tango-icon-library/48/edit-cut-64.png";
// get image from the project war/images folder
String url = GWT.getHostPageBaseURL() + "images/cut.png";
String html = "<div><center><img src = '" + url
+ "'></img></center><label>Cut</label></br></div>";
button.setHTML(html);
Note: you can move it to CSS as well and append in HTML.
___________-
EDIT
You can achieve it using PushButton as well using setInnerHTML()method that will benefit from ImageResource as well.
final PushButton pushButton = new PushButton(new Image(Resources.INSTANCE.old_cut_icon()));
pushButton.getElement().setInnerHTML("<div><center>"+pushButton.getElement().getInnerHTML()+"</center><label><center>Cut</center></label></div>");
now simply call setImage() whenever needed to change the icon only.
pushButton.getUpFace().setImage(new Image(Resources.INSTANCE.new_cut_icon()));
Screenshot
Set a text on your button. Also set a CSS style:
.myButton {
background-image:url('/images/icon/cut.png');
background-position:center top;
padding: 28px 2px 2px;
}
Adjust padding depending on the size of your image.
An alternative approach is to create a widget that combines a button with a label, and either (1) put them in a LayoutPanel, specifying the position that you want, or (2) use CSS to move the label on top of the button (better).

Callback on widget attached and all images are loaded

I want execute some logic after the moment when widget is attached and all images inside this widget are loaded. This widget show a block of html prepared in CMS (so the number of images is dynamic).
What have I tried:
override Widget.onAttach() or Widget.onLoad(). Unfortunately both of them are executed before the moment when all images are loaded.
I found gwt-image-loader library which can add a callback per image. I wan't use it due to dynamic nature of the content.
In JavaScript there is this option which works great:
$('selector').waitForImages(function() {
// do some logic
});
Maybe I missed some GWT way to do the same thing?
You can try GWT's Image.addLoadHandler()
onLoad and onAttach methods are there to inform you that the <img> tag is attached to your document and that is it. This helps in setting image attributes such as height, width, position and so on. What you are asking is, after the image is attached to document you want an handler after the image is rendered. This is not possible with the current version of GWT as per my experience. Further rendering of image depends on the network you are in, the server you are connected and so on. So instead of wanting for a render callback, try to do the work in onLoad or onAttach methods or add a loadHandler for the same

How to refresh an image in gwt?

I have a form with an Image widget and a FileUpload widget.
I can use file upolad to change images.
I'd like to visualise a changed image right after a new image is submited to a servlet. But how can I force an Image widget to grab a new image from server ? (image's url doesn't change, content does) .
If you can't/don't want to change the URL on the server, you can alternatively add a query parameter like:
version++;
image.setUrl(url + "?v" + version);
The query parameter will be ignored on the server (except if you want to use it somehow), but it forces a reload, because the browser doesn't know, if the image might be generated dynamically.
Or better: just set the URL to "" then back to the original URL. Tested in Chrome.
String url = image.getUrl();
image.setUrl("");
image.setUrl(url);

Gtk Spinner Not Appearing

I'm trying to get a Gtk::Spinner object to display while calculations are in progress but nothing appears to be happening. The snippet of code looks like...
{
Gtk::Spinner spinner;
spinner.start ();
// do some work...
spinner.stop ();
}
I'd have thought the spinner needed to know which dialogue it appears over but I can't see any way of feeding that into the object. Does anyone know where I could find a worked example? I can find the Gtk documentation in many places, but that isn't helping much.
In short, here is a quick checklist if Gtk::Spinner is not appearing on screen:
Make sure librsvg is installed.
Check if your currently active Gtk theme has an image file with base name "process-working-symbolic" (e.g. /path/to/your/theme/icons/scalable-up-to-32/status/process-working-symbolic.svg).
In your app code: Make sure you added the spinner object to some parent widget / container: vbox.pack_start(spinner, Gtk::PACK_SHRINK);
In your app code: Ensure all widgets are actually made visible: show_all_children();
In your app code: Finally you need to call spinner.start() for the widget to actually appear and spin on screen.
In detail:
The actual Gtk spinner widget code (see function gtk_spinner_class_init() in gtkspinner.c) is not doing any drawing on its own. In fact its code is very little. All it does is adding CSS code to the gtk widget:
it assigns the CSS class "spinner" to the widget
and it automatically adds and removes the CSS pseudo-class "checked" whenever the widget's boolean gtk property "active" changes.
So the actual look (icon) and the animation is defined by your current theme's CSS file. E.g. in Gtk's default theme's gtk-contained.css file you find the following:
spinner {
background: none;
opacity: 0;
-gtk-icon-source: -gtk-icontheme("process-working-symbolic");
};
Which means it will automatically search for an appropriate image file with base name "process-working-symbolic" in the theme's "icons" directory tree. And the actual spinning animation is defined in the same CSS file by this:
spinner:checked {
opacity: 1;
animation: spin 1s linear infinite;
};
In most other themes these CSS code portions for the spinner widget are pretty much identical.
Now here is a common problem with this: in most themes the spinner image is an SVG file (e.g. typically "process-working-symbolic.svg"), but the stock Gdk pixbuf loaders do not support the SVG format at all. They support a variety of other image file formats, but for actually allowing Gdk/Gtk to load .svg files you need to install a third-party pixbuf loader capable to do so like librsvg.
Alternative:
In case you cannot or don't want to bother to install an SVG capable Gdk pixbuf loader like librsvg, then you can also simply add image file(s) with the same base name, but in another file format like "process-working-symbolic.png" to your theme's icons directory tree. So either draw or download some spinner picture then scale it and place them several times to the resolutions listed in your theme's "icons" directory, e.g.:
/THEMEDIR/icons/8x8/status/process-working-symbolic.png
/THEMEDIR/icons/16x16/status/process-working-symbolic.png
/THEMEDIR/icons/22x22/status/process-working-symbolic.png
/THEMEDIR/icons/24x24/status/process-working-symbolic.png
/THEMEDIR/icons/32x32/status/process-working-symbolic.png
/THEMEDIR/icons/64x64/status/process-working-symbolic.png
/THEMEDIR/icons/256x256/status/process-working-symbolic.png
/THEMEDIR/icons/512x512/status/process-working-symbolic.png
Also you should know: Whenever you do spinner.start() the spinner icon immediately appears on screen, but even on a decent machine it typically takes almost a second before the spinner starts its animation.
Did you call
spinner.show ();
and add it to some window?
Moreover, your calculations may block the UI, so it is not updated. Call
while (Gtk::Main::events_pending ())
Gtk::Main::iteration ();
once in a while.
To change the mouse cursor to "busy" you can do the following:
Glib::RefPtr<Gdk::Window> window = dialog.get_window();
if(window) {
window->set_cursor(Gdk::Cursor(Gdk::WATCH));
Gdk::flush();
}
To change it back, do
window->set_cursor();
instead.
Disclaimer: I usually work with GTK in C, and have translated this on the fly...