Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
Opening a view or component in a new native browser tab
I'm trying to accomplish the following:
Currently my app has a tabsheet holding all the "views", one in each individual tab. Formally they aren't real "views" at all, as they are not registered as them -- thus not having an own url to access them individually and that all. They really hold a Layout each and a component or components inside it.
My aim is to clone / move that tab content to a new browser tab (not Vaadin tab but a native browser one), as a kind of "mega-maximization" of the TabSheet tab. Let's say my tab held a Grid with some data - then I want that grid to be hold in its own browser tab. The ideal user action would be to right click on the TabSheet tab caption, then choose "Open in new browser tab". That part is currently "almost" accomplished, as I used the ContextMenu extension with my TabSheet component as its first parameter so I have yet to determine how to find the "current" tab by clicking over it with right click, but that's not what it bother me at the moment (though any hint on how to accomplish this will be really appreciated, too).
What bothers me is how to "replicat" the content in its own browser tab. What I've done is to use BrowserWindowOpener:
BrowserWindowOpener opener = new BrowserWindowOpener(MyUIForNewNavigatorTab.class); opener.setFeatures(""); opener.extend(hojaDePestanyas);
MyUIForNewNavigatorTab is an UI which extends from the base UI, as the docs say that it needs an UI as its parameter.
As I need to pass a component to this UI which would be the content Layout from the source TableSheet tab I want to replicate and all its children but it shouldn't done in the UI constructor (again, as per the docs) and I cannot overload the init() method, I'm getting some confusion on how to accomplish this (passing a Component to the new UI).
In MyUIForNewNavigatorTab class I created a setComponent(Component c) method which simply does content.addComponent(c), and then try the following:
MyUIForNewNavigatorTab newTabUI = (MyUIForNewNavigatorTab) opener.getUI(); newTabUI.setComponent(c);
but this throws a NPE and, during a debugging session, the contents of newTabUI seem to be my already existing, "main" UI for the application instead of the new created MyUIForNewNavigatorTab.
This is where I currently get lost as I don't know what else to try.
I also want to note that I removed my @PreserveOnRefresh annotation from my main app UI as I suspect that it would interfere with this approach, which I don't know if is right at all.
Can this be accomplished with Vaadin? Is this the right way to follow? Is any way to "communicate" between UIs? And, by the way, that doest BrowserWindowOpener.extend() method does, as it's not documented in the API javadocs? Also, are there any ContextMenu documents out there? They say "the API mimics the MenuBar component in Vaadin and it is pretty self-documenting", but I don't find anywhere what the second parameter for its constructor (a boolean, which in the examples seems to be always set as true) does.
Thanks in advance!
What I've found is that when I do a new BrowserWindowOpener(MyUIForNewNavigatorTab.class) the init() method of that UI class is never fired. Well, what's the purpose of passing it to the BrowserWindowOpener() method? As per the docs,
If the application lets the user open popup windows with a BrowserWindowOpener, each of them has a dedicated special UI provider.
I thought this meant that the provided class would be instantiated and its init() method fired. As it isn't, that explains why I get a NPE when I try to later get it.
Also, after having failed the sequence of actions after right-clicking, I don't know why, my TabSheet responds to left clicks opening new browser tabs. How can this be? How can a NPException inside a ContextClickListener affect it to the point that it changes its behaviour making it respond to left clicks? Sounds very strange to me.