Pass information to new web-browser window/tab being opened with BrowserWindowOpener in Vaadin 8

后端 未结 2 1763
小蘑菇
小蘑菇 2021-01-28 20:08

In Vaadin 8, we can let the user open a new tab/window within their web browser by clicking a button that has been associated with a BrowserWindowOpener. As discussed in the man

相关标签:
2条回答
  • 2021-01-28 20:59

    There are basically three approaches you can use, and combinations of these

    1. Use URI parameters. As you mentioned, this is limited to String type data.

      • You can read the URI fragment in UI with e.g. String uriFragment = Page.getCurrent().getUriFragment();
      • You can read URI parameter using VaadinRequest.getParameter(), VaadinRequest is given as parameter in init(...) of main UI
    2. UI's in different browser tabs share the same Vaadin session. That gives some tools, namely

      • You can use session attributes, i.e. VaadinSession.getCurrent().getAttribute(…) and VaadinSession.getCurrent().setAttribute(…)

      • If you use CDI or Spring, you can Inject / Autowire @VaadinSessionScoped bean. The instance is then bound to Session and hence shared between the tabs.

    3. Read data from database (possibly using 1. and/or 2. as help for keys)

    0 讨论(0)
  • 2021-01-28 21:07

    The Answer by Tatu Lund mentioned passing a URI parameter to the new window being opened.

    Example app, passing URI parameter to new window

    Here is a simple little demonstration app in Vaadin 8.5.0 to show that technique.

    We start with three cats that we pretend to retrieve from a database. Each time the user selects a cat, we get the cat’s identifier, a UUID object. We generate a canonical 32-character hex string representation of that UUID. And we specify that as the parameter value to be passed with the parameter key cat_id. We specify that parameter by calling BrowserWindowOpener::setParameter.

    Note that we do this on the selection of an item in the Grid listing cats. Because of browser restrictions in opening windows, the BrowserWindowOpener must be configured before the user clicks its button. We cannot run code in reaction to the button click, as far as I know.

    The new browser window is populated with an automatically-instantiated subclass of UI. In this case CatUI is what we wrote. In CatUI, we get the URI parameter, extract the string representing the UUID, recreate the UUID object, and then pass that to our pretend database-service to fetch the cat in question. Then a layout’s fields are populated with the Cat object values. We don’t bother with data-binding the cat-to-layout as that is not the point of this demo.

    Caveat: This is just a demo, and ignores issues that are not directly related to issue of passing information via URI parameter to a new window. For example, crucial issues of concurrency are ignored here but would not be in real work.

    This demo consists of four class files, all pasted below.

    • MainUI (opened by default when app launches)
    • CatUI (opened when user clicks button)
    • Cat (business object, with name and id properties)
    • DatabaseService (pretend storehouse of cat records)

    MainUI

    package com.basilbourque.example;
    
    import com.vaadin.annotations.Theme;
    import com.vaadin.annotations.VaadinServletConfiguration;
    import com.vaadin.server.BrowserWindowOpener;
    import com.vaadin.server.VaadinRequest;
    import com.vaadin.server.VaadinServlet;
    import com.vaadin.ui.Button;
    import com.vaadin.ui.Grid;
    import com.vaadin.ui.UI;
    import com.vaadin.ui.VerticalLayout;
    
    import javax.servlet.annotation.WebServlet;
    import java.util.List;
    import java.util.Set;
    import java.util.UUID;
    
    /**
     * This UI is the application entry point. A UI may either represent a browser window
     * (or tab) or some part of an HTML page where a Vaadin application is embedded.
     * <p>
     * The UI is initialized using {@link #init(VaadinRequest)}. This method is intended to be
     * overridden to add component to the user interface and initialize non-component functionality.
     */
    @Theme ( "mytheme" )
    public class MainUI extends UI {
        private Grid< Cat > grid;
        private Button button;
    
        @Override
        protected void init ( VaadinRequest vaadinRequest ) {
            // Configure button to open now browser window/tab.
            this.button = new Button( "Open in new window" );
            BrowserWindowOpener opener = new BrowserWindowOpener( CatUI.class );
            opener.setFeatures( "height=300,width=500,resizable" );
            opener.extend( this.button );
            opener.setParameter( "cat_id" , new UUID(0,0).toString());  // Send nil UUID (all zeros) if nothing selected.
            System.out.println( "BWO URL: " + opener.getUrl() );
            this.button.setEnabled( false );
    
            this.grid = new Grid<>( Cat.class );
            this.grid.setCaption( "Cats" );
            List<Cat> cats = new DatabaseService().fetchAllCats() ;
            this.grid.setItems( cats  );
            // Every time the user selects a cat in the Grid, assign that cat’s ID to our `BrowserWindowOpener`. This way our button is always prepared to open a window for the selected cat.
            this.grid.addSelectionListener( event -> {
                Set< Cat > selectedCats = event.getAllSelectedItems();
                this.button.setEnabled( selectedCats.size() > 0 );
                if ( selectedCats.size() > 0 ) {  // If the user selected an item.
                    Cat cat = selectedCats.stream().findFirst().get();
                    opener.setParameter( "cat_id" , cat.getId().toString() );  // A UUID’s canonical presentation is as a 36-character hexadecimal string in five groups with HYPHEN-MINUS as delimiter.
                } else {
                    opener.setParameter( "cat_id" , new UUID(0,0).toString());  // Send nil UUID (all zeros) if nothing selected.
                }
                System.out.println( "BWO URL: " + opener.getUrl() );
            } );
            this.grid.select( cats.stream().findFirst().get() ); // Select first item arbitrarily, to provoke the grid’s selection-listener above to fire.
    
            button.addClickListener( e -> {
                System.out.println( "BASIL opening now window" );
            } );
    
            final VerticalLayout layout = new VerticalLayout();
            layout.addComponents( this.grid , button );
            setContent( layout );
        }
    
        @WebServlet ( urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true )
        @VaadinServletConfiguration ( ui = MainUI.class, productionMode = false )
        public static class MyUIServlet extends VaadinServlet {
        }
    }
    

    CatUI

    package com.basilbourque.example;
    
    import com.vaadin.server.VaadinRequest;
    import com.vaadin.ui.*;
    
    import java.util.Optional;
    import java.util.UUID;
    
    public class CatUI extends UI {
        private Cat cat = null;
    
        @Override
        protected void init ( VaadinRequest vaadinRequest ) {
            // Retrieve a parameter from the URI of this UI/window.
            String catUuidString = vaadinRequest.getParameter( "cat_id" );  // In the URI key-value parameters, "cat_id" is our key, and a UUID’s hex string is the expected value.
            if ( null == catUuidString ) {  // If we did not receive the UUID-string parameter we expected.
                this.setContent( this.buildLayoutForNoCat( null ) );
                return;
            }
            UUID uuid = UUID.fromString( catUuidString );  // Rehydrate the `UUID` from our passed hex string representing the UUID’s value.
            Optional< Cat > cat = new DatabaseService().fetchCat( uuid );
            if ( cat.isPresent() ) {  // NULL check.
                System.out.println( "uuidString: " + uuid + " and cat: " + cat.get() );
                this.setContent( this.buildLayoutForCat( cat.get() ) );  // Retrieve the `Cat` object from our `Optional< Cat >` object by calling `get()` only after checking for NULL.
                return;
            } else {  // Failed to find cat.
                this.setContent( this.buildLayoutForNoCat( uuid ) );
                return;
            }
        }
    
        private Layout buildLayoutForCat ( Cat cat ) {
            this.cat = cat ;
            this.getPage().setTitle( "Cat details" );
    
            // Have some content for it
            TextField name = new TextField( "Name: " );
            name.setWidth( 100 , Unit.PERCENTAGE );
            name.setValue( this.cat.getName() );
    
            TextField id = new TextField( "Id: " );
            id.setWidth( 100 , Unit.PERCENTAGE );
            id.setValue( this.cat.getId().toString() );
    
            VerticalLayout layout = new VerticalLayout();
            layout.addComponent( name );
            layout.addComponent( id );
            return layout;
        }
    
        private Layout buildLayoutForNoCat ( UUID uuid ) {
            VerticalLayout layout = new VerticalLayout();
            String message = "No cat found for the id: " + uuid;
            Label label = new Label( message );
            layout.addComponentsAndExpand( label );
            return layout;
        }
    }
    

    Cat

    package com.basilbourque.example;
    
    import java.util.UUID;
    
    public class Cat {
        private UUID id;
        private String name;
    
        public Cat ( UUID id , String name ) {
            this.id = id;
            this.name = name;
        }
    
        public UUID getId () {
            return id;
        }
    
        public void setId ( UUID id ) {
            this.id = id;
        }
    
        public String getName () {
            return name;
        }
    
        public void setName ( String name ) {
            this.name = name;
        }
    
        // Override `Object`.
    
        @Override
        public String toString () {
            return "Cat{ " +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    " }";
        }
    
    
    }
    

    DatabaseService

    package com.basilbourque.example;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Optional;
    import java.util.UUID;
    
    // Pretending to be our gateway to a database.
    public class DatabaseService {
        static private List< Cat > cats;
    
        {
            DatabaseService.cats = List.of(  // Produces an unmodifiable list. (A new feature in Java 9 and later.)
                    new Cat( UUID.fromString( "adf5c1a0-912e-11e8-9eb6-529269fb1459" ) , "Fluffy" ) ,
                    new Cat( UUID.fromString( "d37401c6-912e-11e8-9eb6-529269fb1459" ) , "Spot" ) ,
                    new Cat( UUID.fromString( "de29b6d8-912e-11e8-9eb6-529269fb1459" ) , "Lilly Mae" )
            );
        }
    
        public List< Cat > fetchAllCats () {
            return new ArrayList<>( DatabaseService.cats );  // Copy the list, then return.
        }
    
        public Optional< Cat > fetchCat ( UUID uuid ) {
            return DatabaseService.cats.stream().filter( cat -> cat.getId().equals( uuid ) ).findFirst();
        }
    
        public static void main ( String[] args ) {
            Optional< Cat > cat = new DatabaseService().fetchCat(  UUID.fromString( "de29b6d8-912e-11e8-9eb6-529269fb1459" ) );
            if ( cat.isPresent() ) {
                System.out.println( "cat: " + cat.get() );
            } else {
                System.out.println( "No cat found." );
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题