Vaadin Spring Navbar - html

I am trying to add a navbar (just like bootstrap's) for a Spring application but am not getting the nav menu to appear on the web page!
Can anyone please tell me what's wrong here?
Below is my code:
private Panel viewContainer;
private HorizontalLayout navbar;
private Button btnHome;
private Button btnNested;
private Button createNavigationButton(String caption, final String viewName) {
Button button = new Button(caption);
button.addStyleName(ValoTheme.BUTTON_SMALL);
// If you didn't choose Java 8 when creating the project, convert this
// to an anonymous listener class
button.addClickListener(event -> getUI().getNavigator().navigateTo(
viewName));
return button;
}
#Override
protected void init(VaadinRequest request) {
final VerticalLayout root = new VerticalLayout();
root.setSizeFull();
navbar = new HorizontalLayout();
navbar.setWidth("100%");
navbar.setDefaultComponentAlignment(Alignment.MIDDLE_RIGHT);
root.addComponent(navbar);
final Label brand = new Label("Nested demo");
brand.addStyleName(ValoTheme.LABEL_H1);
brand.addStyleName(ValoTheme.LABEL_NO_MARGIN);
navbar.addComponent(brand);
navbar.setComponentAlignment(brand, Alignment.MIDDLE_LEFT);
navbar.setExpandRatio(brand, 1);
btnHome = new Button("Home", FontAwesome.HOME);
btnHome.addStyleName(ValoTheme.BUTTON_BORDERLESS);
navbar.addComponent(btnHome);
btnNested = new Button("nested", FontAwesome.COFFEE);
btnNested.addStyleName(ValoTheme.BUTTON_BORDERLESS);
navbar.addComponent(btnNested);
viewContainer = new Panel();
viewContainer.setSizeFull();
root.addComponent(viewContainer);
root.setExpandRatio(viewContainer, 1);
}
Any hint is much appreciated.
Thanks

Henri's comment is almost certainly the correct answer.
Judging by the init(VaadinRequest) code you're using a UI class.
Without setContent(some components with visible stuff in them);
you won't see anything.
'you won't see anything' happens a lot in Vaadin when you're attempting new things, or doing proof of concept stuff. IMHO it's always a good practice to start with really dumb UI stuff e.g. setContent(new Label("TODO - implement this content-xxx"));
Using browser dev-tools is also a great idea. A quick select-element should show you that the UI div is empty, and allow you to start diagnosing.
TL;DR :-
UI is a ComponentContainer, so you need to - either
setContent(myLayoutWithStuff);
or
getContent().addComponent(myStuff);
to show someStuff.

Related

MvvmCross, Mvx.MvxListView and custom binding in MvxItemTemplate

In a MvvmCross app, I have a page with the classic chat behavior (WhatsApp like): this page shows the history of messages exchanged between two users with the last message at the bottom of the list.
I've successfully implemented the view in Windows Phone 8.1, but I'm struggling with a problem in Android.
I'll give you a short introduction and description of my problem and next I'll go through technical details.
INTRODUCTION
Actually, my need is to apply different style to messages sent by different users: tipically align left messages sent from other user and align right messages sent by me (I do this through the weight property); I need to apply a different drawable background and set different gravity property also.
I use custom binding because, AFAIK, those properties cannot be binded with classic binding: local:MvxBind="Gravity MyPropery" doesn't work because there is no Gravity property.
So, I have of course two axml files:
the first one contains the Mvx.MvxListView
the second one contains the item template for MvxListView
And I've created three different custombinding (for Background, Gravity and Weight) following these guides:
http://slodge.blogspot.it/2013/06/n28-custom-bindings-n1-days-of-mvvmcross.html
In MvvmCross how do I do custom bind properties
THE PROBLEM
I want that, when a user opens the chat View, the list widget shows automatically the last message. To accomplish this, I scroll programmatically the list to the last message and this seems to be the problem.
If I don't scroll programmatically, when I open the page and scroll manually to the end of the page, all custom bindings are applied successfully: I can see messages aligned right and left, with correct background and weight applied.
If I force the scroll programmatically, when I open the page I see a strange behavior: all the messages are present (classic binding, such as Text property, have been successfully applied), but custom bindings are missing. All the messages have the same background and are all left aligned.
BUT, if I scroll manually up and down, the custom binding are processed and the messages are displayed with right style.
DEBUG ANALYSIS
To debug the behaviour I've put a simple static counter in a custom binding procedure to track every time the function is processed.
public class LinearLayoutWeightTargetBinding : MvxAndroidTargetBinding
{
public static int debugCounter = 0;
public LinearLayoutWeightTargetBinding(object target) : base(target)
{
}
protected LinearLayout MyTarget
{
get { return (LinearLayout)Target; }
}
public override Type TargetType { get { return typeof(bool); } }
protected override void SetValueImpl(object target, object value)
{
var ll = (LinearLayout)target;
var itsMe = (bool)value;
var weight = itsMe ? (float)20.0 : (float)5.0;
var layoutParams = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WrapContent, weight);
ll.LayoutParameters = layoutParams;
Log.Debug("MeeCHAT", string.Format("LinearLayoutWeightTargetBinding::SetValueImpl::ItsMe:{0} - counter:{1}", itsMe, ++debugCounter));
}
public override MvxBindingMode DefaultMode { get {return MvxBindingMode.TwoWay;} }
}
By this way I saw that actually by scrolling up and down the custom bindings are applied (debugCounter increases correctly).
BUT when I apply the programmatically scroll, only the first 10 items are processed by the custom bindings and this seems the reason why I see the messages without the right style. Because I have a long list, only the first 10 items are processed but they are not visible (they are out of the visible area) and the visibile items have not been processed.
TECHNICAL DETAILS
Here are some details related to technical aspects of my app. I try to give you all important aspects.
ORGANIZATION OF THE VIEWS
By following the approach described by Greg Shackles in this article http://gregshackles.com/presenters-in-mvvmcross-navigating-android-with-fragments/ I have just one general Activity for the app and one Fragment for each View; then through a Presenter is possible to activate the right ViewModel and manage the stack of the navigation.
The Fragment for the View where I have the Mvx.MvxListView widget is
public class MyMatchersChatView : MvxFragment
{
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var ignore = base.OnCreateView(inflater, container, savedInstanceState);
var result = this.BindingInflate(Resource.Layout.MyMatchersChatView, null);
var headerFrame = result.FindViewById<FrameLayout>(Resource.Id.headerFrameMyMatchersChatView);
var headerWidget = new HeaderWidget() { ViewModel = this.ViewModel };
var tran = ChildFragmentManager.BeginTransaction();
tran.Add(headerFrame.Id, headerWidget, "headerMyMatchersChat");
tran.Commit();
var listView = result.FindViewById<MvxListView>(Resource.Id.messagesList);
listView.SetSelection(listView.Adapter.Count - 1); // Scroll to the end of the list
return result;
}
}
The statement listView.SetSelection(listView.Adapter.Count - 1); force the list to scroll to the end.
Last two things: how the custom bindings are registered and how are applied in axml file.
REGISTRATION OF CUSTOM BINDING
In Setup.cs I have:
protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry)
{
base.FillTargetFactories(registry);
registry.RegisterFactory(new MvxCustomBindingFactory<LinearLayout>("CustomWeight",
(b) => new LinearLayoutWeightTargetBinding(b)));
}
APPLYING OF CUSTOM BINDING
In my axml I have:
<LinearLayout
android:orientation="horizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
local:MvxBind="CustomWeight IsCurrentUser">
LISTVIEW AND VIEWMODEL
Here is the code of ListView
<Mvx.MvxListView
android:id="#+id/messagesList"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
local:MvxBind="ItemsSource MyMessages"
local:MvxItemTemplate="#layout/mymatcherschatview_itemtemplate" />
and the property in ViewModel
private IEnumerable<MyMatchMessageModel> _myMessages;
public IEnumerable<MyMatchMessageModel> MyMessages
{
get { return _myMessages; }
set
{
_myMessages = value;
RaisePropertyChanged(() => MyMessages);
}
}
ENVIRONMENT
Finally, here is my environment:
Visual Studio 2015
MvvmCross 3.5.1
Core targets: .NET Framework 4.5, Windows 8, ASP.NET Core 5.0, Windows Phone 8.1, Xamarin.Android, Xamarin.iOS, Xamarin.iOS (Classic)
The Android app target is API Level 19 (Xamarin.Android v4.4 Support)
Xamarin 3.11.1450.0
Xamarin.Android 5.1.6.7
Someone can help me to understand if I'm doing something wrong?
Thanks for reading and for any help!
>>EDIT 1<<
I've changed my layout by adding stackFromBottom and transcriptMode properties and by removing the scrolling to below programmatically in Fragment obtaining an auto-scroll behavior, but the problem still remains: to see messages with correct style I have to manually scroll up and down (to activate the custom bindings)
Here is the new axml...
<Mvx.MvxListView
android:id="#+id/messagesList"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stackFromBottom="true"
android:transcriptMode="alwaysScroll"
local:MvxBind="ItemsSource MyMessages"
local:MvxItemTemplate="#layout/mymatcherschatview_itemtemplate" />
...and the new code in Fragment
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var ignore = base.OnCreateView(inflater, container, savedInstanceState);
var result = this.BindingInflate(Resource.Layout.MyMatchersChatView, null);
var headerFrame = result.FindViewById<FrameLayout>(Resource.Id.headerFrameMyMatchersChatView);
var headerWidget = new HeaderWidget() { ViewModel = this.ViewModel };
var tran = ChildFragmentManager.BeginTransaction();
tran.Add(headerFrame.Id, headerWidget, "headerMyMatchersChat");
tran.Commit();
return result;
}
First thing I would do is to make sure that your custom binding is always getting called.
Set a breakpoint on the SetValueImpl() method and check it´s getting called on those problematic items. If that happens, then the issue relies on the view no getting updated for any reason and you should work on that. If it doesn´t break, you will know for sure it´s a custom binding problem (possibly a bug) in MvxAdapter.
If you find out it´s the second one. I would suggest getting rid of your custom binding and creating your own ChatListAdapter : MvxAdapter as follows:
public class CoolChatListAdapter : MvxAdapter
{
public CoolChatListAdapter(Context context, IMvxAndroidBindingContext bindingContext) : base(context, bindingContext)
{
}
protected override View GetBindableView(View convertView, object source, int templateId)
{
var item = source as MyMatchMessageModel;
var weight = item.IsCurrentUser ? (float) 20.0 : (float) 5.0;
var ll = (LinearLayout) convertView;
var layoutParams = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WrapContent, weight);
ll.LayoutParameters = layoutParams;
return base.GetBindableView(convertView, source, templateId);
}
}
Then, in your android view:
var adapter = new ChatListAdapter(this, (IMvxAndroidBindingContext)BindingContext);
_chatList = FindViewById<MvxListView>(Resource.Id.chat_list_view);
_chatList.Adapter = adapter;

android lollipop toolbar: how to hide/show the toolbar while scrolling?

I'm using the new toolbar widget introduced in the appcompat / support-v7. I would like to hide/show the toolbar depending on if the user is scrolling up/down the page, just like in the new Google's playstore app or NewsStand app. Is there something built into the toolbar widget for this or should I be using it in conjunction with FrameLayout and ObservableScrollView?
As far as I know there is nothing build in that does this for you. However you could have a look at the Google IO sourcecode, especially the BaseActivity. Search for "auto hide" or look at onMainContentScrolled
In order to hide the Toolbar your can just do something like this:
toolbar.animate().translationY(-toolbar.getBottom()).setInterpolator(new AccelerateInterpolator()).start();
If you want to show it again you call:
toolbar.animate().translationY(0).setInterpolator(new DecelerateInterpolator()).start();
For hiding the toolbar you can just do :
getSupportActionBar().hide();
So you just have to had a scroll listener and hide the toolbar when the user scroll !
Hide:
getSupportActionBar().hide();
Show:
getSupportActionBar().show();
The answer is straightforward. Just implement OnScrollListenerand hide/show your toolbar in the listener. For example, if you have listview/recyclerview/gridview, then follow the example.
In your MainActivity Oncreate method, initialize the toolbar.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
if (toolbar != null) {
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
}
And then implement the OnScrollListener
public RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() {
boolean hideToolBar = false;
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (hideToolBar) {
((ActionBarActivity)getActivity()).getSupportActionBar().hide();
} else {
((ActionBarActivity)getActivity()).getSupportActionBar().show();
}
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 20) {
hideToolBar = true;
} else if (dy < -5) {
hideToolBar = false;
}
}
};
I got the idea from: https://stackoverflow.com/a/27063901/1079773
Android Design Support Library can be used to show/hide toolbar.
See this.
http://android-developers.blogspot.kr/2015/05/android-design-support-library.html
And there are detail samples here.
http://inthecheesefactory.com/blog/android-design-support-library-codelab/en
There are actually quite a number of ways to hide/show the toolbar while you are scrolling the content. One of the ways is to do it via the Android Design Support Library or more specifically the Coordinator layout aka. super-powered frame layout.
Basically all you need to do is to have the following structure in your layout file and you should be able to achieve the result that you want.
<CoordinatorLayout>
<AppBarLayout>
</AppBarLayout>
<NestedScrollView>
</NestedScrollView>
</CoordinatorLayout>
I have actually made a video to explain how it can be done in a step by step manner. Feel free to check it out and let me know if it helps. Thanks! :)
https://youtu.be/mEGEVeZK7Nw
Just add this property inside your toolbar and its done
app:layout_scrollFlags="scroll|enterAlways"
Isn't is awesome
I've been trying to implement the same behavior, here is the brunt of code showing and hiding the toolbar (put in whatever class containing your RecyclerView):
int toolbarMarginOffset = 0
private int dp(int inPixels){
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, inPixels, getApplicationContext().getResources().getDisplayMetrics());
}
public RecyclerView.OnScrollListener onScrollListenerToolbarHide = new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
toolbarMarginOffset += dy;
if(toolbarMarginOffset>dp(48)){
toolbarMarginOffset = dp(48);
}
if(toolbarMarginOffset<0){
toolbarMarginOffset = 0;
}
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams)toolbar.getLayoutParams();
params.topMargin = -1*toolbarMarginOffset;
toolbar.setLayoutParams(params);
}
};
I've included the dp function to convert from pixels to dp but obviously set it to whatever your toolbar height is. (replace dp(48) with your toolbar height)
Where-ever you setup your RecyclerView include this:
yourListView.setOnScrollListener(onScrollListenerToolbarHide);
However, there are a couple additional issues if you are also using a SwipeRefreshLayout.
I've had to set the marginTop of the first element in the adapter for the RecyclerView to the Toolbar's height plus original offset. (A bit of a hack I know). The reason for this is I found that if I changed my above code to include changing the marginTop of the recyclerView while scrolling it was a jittery experience. So that's how I overcame it. So basically setup your layout so that your toolbar is floating on top of the RecyclerView (clipping it) Something like this (in onBindViewHolder of your custom RecyclerView adapter) :
if(position==0){
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams)holder.card.getLayoutParams();
// params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
params.topMargin = dp(10+48);
}
And lastly, since there is a large offset the RecyclerViews refresh circle will be clipped, so you'll need to offset it (back in onCreate of your class holding your RecyclerView):
swipeLayout.setProgressViewOffset(true,dp(48),dp(96));
I hope this helps someone. Its my first detailed answer so I hope I was detailed enough.
To hide the menu for a particular fragment:
setHasOptionsMenu(true); //Inside of onCreate in FRAGMENT:
#Override
public void onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.action_search).setVisible(false);
}
I implemented a utility class to do the whole hide/show Toolbar animation when scrolling. You can see the article here http://rylexr.tinbytes.com/2015/04/27/how-to-hideshow-android-toolbar-when-scrolling-google-play-musics-behavior/. Source code is here https://github.com/rylexr/android-show-hide-toolbar.
A library and demo with the complete source code for scrolling toolbars or any type of header can be downloaded here:
https://github.com/JohannBlake/JBHeaderScroll
Headers can be Toolbars, LinearLayouts, RelativeLayouts, or whatever type of view you use to create a header.
The scrollable area can be any type of scroll content including ListView, ScrollView, WebView, RecyclerView, RelativeLayout, LinearLayout or whatever you want.
There's even support for nested headers.
It is indeed a complex undertaking to synchronize headers (toolbars) and scrollable content the way it's done in Google Newsstand.
This library doesn't require implementing any kind of onScrollListener.
The solutions listed above by others are only half baked solutions that don't take into consideration that the top edge of the scrollable content area beneath the toolbar has to initially be aligned to the bottom edge of the toolbar and then during scrolling the content area needs to be repositioned and possibly resized. The JBHeaderScroll handles all these issues.
There is an Android library called Android Design Support Library that's a handy library where you can find of all of those Material fancy design things that the Material documentation presents without telling you how to do them.
It's well presented in this Android Blog post. The "Collapsing Toolbar" in particular is what you're looking for.

How to do CreateBindingSet() on Windows Phone?

In the N+1 video #34 (Progress), there was an example of using CreateBindingSet() for the Android version, which is not typical. But the narrator also mentioned briefly that the same can be done on the Windows platform.
As much as I tried, however, I am unable to get a View's property to be bound to its ModelView on the Windows Phone. I always get a NullReferenceException.
The closest I came was the code below, including suggestions from ReSharper. Here's my FirstView.xaml.cs:
using Cirrious.MvvmCross.Binding.BindingContext;
using Whatever.ViewModels;
namespace Whatever {
// inheriting from IMvxBindingContextOwner was suggested by ReSharper also
public partial class FirstView : BaseView, IMvxBindingContextOwner {
public class MyBindableMediaElement
{
private string _theMediaSource = "whatever";
public string TheMediaSource
{
get
{
return _theMediaSource;
}
set
{
_theMediaSource = value;
}
}
}
public FirstView()
{
InitializeComponent();
_mediaElement = new MyBindableMediaElement(this.theMediaElement);
var set = this.CreateBindingSet<FirstView, FirstViewModel>();
// the corresponding view model has a .SongToPlay property with get/set defined
set.Bind(_mediaElement).For(v => v.TheMediaSource).To(vm => vm.SongToPlay);
set.Apply();
}
public IMvxBindingContext BindingContext { get; set; } // this was suggested by ReSharper
}
I get a NullReferenceException in MvxBaseFluentBindingDescription.cs as soon as the view is created. The exact location is below:
protected static string TargetPropertyName(Expression<Func<TTarget, object>> targetPropertyPath)
{
var parser = MvxBindingSingletonCache.Instance.PropertyExpressionParser; // <----- exception here**
var targetPropertyName = parser.Parse(targetPropertyPath).Print();
return targetPropertyName;
}
I have not seen a working example of creating a binding set on a Windows Phone emulator. Has anyone gotten this to work? Thanks.
I can confirm that the narrator said that remark a little too flippantly without actually thinking about how he might do it...
However, with a little effort, you definitely can get the CreateBindingSet to work in Windows if you want to.
Before you start, do consider some alternatives - in particular, I suspect most people will use either Windows DependencyProperty binding or some hand-crafted code-behind with a PropertyChanged event subscription.
If you do want to add CreateBindingSet code to a Windows project then:
Add the Binding and BindingEx assemblies to your Ui project - the easiest way to do this is using nuget to add the BindingEx package.
In your Setup class, override InitializeLastChance and use this opportunity to create a MvxWindowsBindingBuilder instance and to call DoRegistration on that builder. Both these first two steps are covered in the n=35 Tibet binding video - and it's this second step that will initialise the binding framework and help you get past your current 'NullReferenceException' (for the code, see BindMe.Store/Setup.cs)
In your view, you'll need to implement the IMvxBindingContextOwner interface and you'll need to ensure the binding context gets created. You should be able to do this as simply as BindingContext = new MvxBindingContext();
In your view, you'll need to make sure the binding context is given the same DataContext (view model) as the windows DataContext. For a Phone Page, the easiest way to do this is probably just to add BindingContext.DataContext = this.ViewModel; to the end of your phone page's OnNavigatedTo method. Both steps 3 and 4 could go in your BaseView if you intend to use Mvx Binding in other classes too.
With this done, you should be able to use the CreateBindingSet code - although do make sure that all binding is done after the new MvxBindingContext() has been created.
I've not got a windows machine with me right now so I'm afraid this answer code comes untested - please do post again if it does or doesn't work.
I can confirm it works almost perfectly; the only problem is, there are no defaults register, so one has to do the full binding like:
set.Bind(PageText).For(c => c.Text).To(vm => vm.Contents.PageText).OneTime();
to fix this, instead of registering MvxWindowsBindingBuilder, I am registering the following class. Note: I have just created this class, and needs testing.
public class UpdatedMvxWindowsBindingBuilder : MvxWindowsBindingBuilder
{
protected override void FillDefaultBindingNames(IMvxBindingNameRegistry registry)
{
base.FillDefaultBindingNames(registry);
registry.AddOrOverwrite(typeof(Button), "Command");
registry.AddOrOverwrite(typeof(HyperlinkButton), "Command");
//registry.AddOrOverwrite(typeof(UIBarButtonItem), "Clicked");
//registry.AddOrOverwrite(typeof(UISearchBar), "Text");
//registry.AddOrOverwrite(typeof(UITextField), "Text");
registry.AddOrOverwrite(typeof(TextBlock), "Text");
//registry.AddOrOverwrite(typeof(UILabel), "Text");
//registry.AddOrOverwrite(typeof(MvxCollectionViewSource), "ItemsSource");
//registry.AddOrOverwrite(typeof(MvxTableViewSource), "ItemsSource");
//registry.AddOrOverwrite(typeof(MvxImageView), "ImageUrl");
//registry.AddOrOverwrite(typeof(UIImageView), "Image");
//registry.AddOrOverwrite(typeof(UIDatePicker), "Date");
//registry.AddOrOverwrite(typeof(UISlider), "Value");
//registry.AddOrOverwrite(typeof(UISwitch), "On");
//registry.AddOrOverwrite(typeof(UIProgressView), "Progress");
//registry.AddOrOverwrite(typeof(IMvxImageHelper<UIImage>), "ImageUrl");
//registry.AddOrOverwrite(typeof(MvxImageViewLoader), "ImageUrl");
//if (_fillBindingNamesAction != null)
// _fillBindingNamesAction(registry);
}
}
This is a skeleton from Touch binding, and so far I have only updated three controls to test out (Button, HyperButton and TextBlock)

RootFrame UriMapper for Caliburn Micro

I have been googling on how to actually implement this with no avail. Could not find a single resource on how to actually do it using Caliburn Micro.
Basically, I am trying this http://www.developer.nokia.com/Community/Wiki/OAuth_on_Windows_Phone
In the example, it used redirect_uri as normal link. I did it with Protocol/File Association (refer http://www.developer.nokia.com/Community/Wiki/URI_associations_for_Windows_Phone_8). Everything works fine. I got it to work without Caliburn Micro.
But based on that example, I would require to implement UriMapperBase and assigned it to RootFrame.UriMapper.
My question is how do I actually implement UriMapper with CaliburnMicro for WP8. For Win 8, it is different as I could override the OnActivate and check for the ActivationKind.Protocol and there is no need for UriMapper.
Ok. Finally managed to get it to work. So, will post it here because I'm pretty sure there will be a lost soul again like me who will appreciate the answer to this.
To use UriMapper in Caliburn, you will need to override the CreatePhoneApplicationFrame in the bootsrapper.
In Boostrapper.cs
protected override PhoneApplicationFrame CreatePhoneApplicationFrame()
{
// var frame = base.CreatePhoneApplicationFrame(); this doesnt work
var frame = new PhoneApplicationFrame(); // this works
frame.UriMapper = new AssociationUriMapper();
return frame;
}
AssociationUriMapper.cs - I just followed the example as per links above
public class AssociationUriMapper : UriMapperBase
{
private string tempUri;
public override Uri MapUri(Uri uri)
{
tempUri = System.Net.HttpUtility.UrlDecode(uri.ToString());
// URI association launch for contoso.
if (tempUri.Contains("pocketthis:MainPage"))
{
// Get the category ID (after "CategoryID=").
//int categoryIdIndex = tempUri.IndexOf("CategoryID=") + 11;
//string categoryId = tempUri.Substring(categoryIdIndex);
// Views/MainPage.xaml returns external exception,
// so remember the / before views
return new Uri("/Views/MainPage.xaml", UriKind.Relative);
}
// Otherwise perform normal launch.
return uri;
}
}
Hope this will help anyone trying to implement Uri/File Association in WP8 with Caliburn Micro.

how to display a video from a JList?

I am currently doing an application using Swing and i am stuck at a certain point. In my function, i have to link videos from a JList. The problem is i am not sure how to link the videos from the JList. I am using an OpenBrowser class to link the video to the internet. I did consider using JButton but i would have to hardcode it and that would be ugly. Is there any other alternatives to do this? I am in desperate need and would be eternally grateful to whoever that can help me.
Safa :)
If you don't want to open a browser with the video using a selection listener, you can consider the idea of launching it with a double click on a JList entry.
sample code
String[] items = {"i1", "i2", "i3", "i4"};
JList list = new JList(items);
list.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent evt) {
JList list = (JList)evt.getSource();
if (evt.getClickCount() == 2) { //check if it is a Double-click
int index = list.locationToIndex(evt.getPoint());
// do whatever you want with the entry at that index
}
}
});
Desktp classes to browse some site (sample code):
if (desktop.isSupported(Desktop.Action.BROWSE)) {
URI uri = new URI("http://www.google.com");
desktop.browse(uri);
}
The desktop.browse() call will open your favourite browser with the given URL.