├── .gitignore ├── README.md ├── docs ├── create.md ├── elements-applogic.md ├── elements-buildui.md ├── images │ ├── todo-list-01.png │ ├── todo-list-02.png │ ├── todo-list-03.png │ ├── todo-list-04.png │ ├── todo-list-05.png │ ├── todo-list-06.png │ ├── todo-list-07.png │ └── todo-list-08.png ├── introduction.md ├── widgets-applogic.md └── widgets-buildui.md ├── elements-todo-list ├── pom.xml └── src │ └── main │ ├── java │ └── org │ │ └── gwtproject │ │ └── tutorial │ │ ├── TodoList.gwt.xml │ │ └── client │ │ ├── Item.java │ │ ├── Item.ui.xml │ │ ├── Main.java │ │ ├── Main.ui.xml │ │ └── TodoList.java │ └── webapp │ ├── TodoList.css │ ├── TodoListElements.html │ ├── WEB-INF │ └── web.xml │ └── favicon.ico ├── pom.xml └── widgets-todo-list ├── pom.xml └── src └── main ├── java └── org │ └── gwtproject │ └── tutorial │ ├── TodoList.gwt.xml │ └── client │ ├── Dialogs.java │ ├── Dialogs.ui.xml │ ├── Item.java │ ├── Item.ui.xml │ ├── Main.java │ ├── Main.ui.xml │ └── TodoList.java └── webapp ├── TodoListWidgets.html └── WEB-INF └── web.xml /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .settings 3 | .project 4 | target 5 | www 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## GWT-Polymer-TODO 2 | 3 | [0]: https://www.polymer-project.org/1.0/ 4 | [2]: http://www.google.es/design/spec/material-design/introduction.html 5 | [3]: https://github.com/vaadin/gwt-polymer-elements 6 | [4]: https://github.com/vaadin/gwt-api-generator 7 | [5]: http://manolo.github.io/gwt-polymer-todo-list/demo/TodoListWidgets.html 8 | [6]: http://manolo.github.io/gwt-polymer-todo-list/demo/TodoListElements.html 9 | 10 | A **TodoList** GWT application for mobile and desktop using [Material Design][2] specification. 11 | 12 | It relies the UI part on [Polymer][0], Paper Elements [collections][5], and a the [gwt-polymer-elements][3] wrapper. 13 | 14 | In this repository, you have two versions of the **TodoList** application, one is built using classic GWT widgets, and another with modern JsInterop Elements. 15 | 16 | ## Demos 17 | Try our 18 | [demo-widgets][5] 19 | or 20 | [demo-elements][6] 21 | 22 | to see the application in action. 23 | 24 | ## Building 25 | 26 | 1. Asuming that you already have a running version of `git` and `maven`, check out the github project: 27 | 28 | $ git clone https://github.com/manolo/gwt-polymer-todo-list.git 29 | 30 | 2. Change to the new folder and run maven 31 | 32 | $ cd gwt-polymer-todo-list 33 | $ mvn clean package 34 | 35 | 3. Run any web server in the `www` folder 36 | 37 | $ serve www 38 | 39 | -------------------------------------------------------------------------------- /docs/create.md: -------------------------------------------------------------------------------- 1 | # Creating the *TodoList* Project 2 | 3 | In this section, we’ll create the **TodoList** project from scratch using GWT’s [webAppCreator](http://www.gwtproject.org/doc/latest/RefCommandLineTools.html#webAppCreator), a command-line utility. 4 | 5 | Before we start, make sure to download the most recent [GWT distribution](../../../download.html) and install [Maven](https://maven.apache.org/). 6 | 7 | ## Using webAppCreator 8 | 9 | The `webAppCreator` is a command-line tool included in the GWT SDK. It generates the project structure necessary to get started. It also creates a starter application, which you can run to ensure that the components are created and linked successfully. 10 | 11 | As you develop your software, you’ll replace the code in the starter application with yours. 12 | 13 | For the **TodoList** project, we’ll need to run `webAppCreator` with the following parameters: 14 | 15 | 16 | | Parameter | Definition | Example | 17 | | ---------- | -----------------------------------------------| ------------ | 18 | | -templates | Comma separated templates to use | maven,sample | 19 | | -out | The directory to place the generated files. | TodoList | 20 | | moduleName | The name of the GWT module you want to create. | org.gwtproject.tutorial.TodoList | 21 | 22 | 23 | ## Setting up a new project. 24 | 25 | 1. Create the **TodoList** application. 26 | 27 | GWT webAppCreator will generate the project structure and the build script (maven pom.xml). 28 | 29 | $ /full_path_to_gwt_sdk/webAppCreator \ 30 | -templates maven,sample \ 31 | -out TodoListApp \ 32 | org.gwtproject.tutorial.TodoList 33 | 34 | _**Tip**: If you include the GWT SDK folder in your PATH environment variable, you won’t have to specify the full path._ 35 | 36 | 37 | 2. Run the application in [SuperDevMode](articles/superdevmode.html). 38 | 39 | To check that the project was created correctly start the new app in SuperDevMode. 40 | 41 | $ cd TodoListApp 42 | $ mvn gwt:run 43 | 44 | _**Tip**: Since the created project is built with Maven, you can import it in Eclipse, IDEA, etc._ 45 | 46 | 3. Launch your Browser. 47 | 48 | In the GWT developer window, press “Launch Default Browser” to launch the application. Alternatively, you can click “Copy to Clipboard” and paste the URL into any browser. 49 | 50 | If you change something in the code, you can recompile the application by simply reloading the web page. If you change configuration files, e.g. pom.xml or static content in webapp, you might have to restart SuperDevMode. `Ctrl+C` and `mvn gwt:run` stops and starts the execution, respectively. 51 | 52 | ## Customizing your project 53 | 54 | With the base project set up, we’ll now add the necessary external dependencies. At the same time, we’ll also remove some of the files and dependencies that are set up and generated by default when the starter application was built. 55 | 56 | 57 | 1. Add the vaadin `gwt-polymer-elements` dependency to your project by editing the `pom.xml` file. 58 | 59 | 60 | com.vaadin.polymer 61 | vaadin-gwt-polymer-elements 62 | ${gwtPolymerVersion} 63 | provided 64 | 65 | 66 | _**Note**: Replace the `${gwtPolymerVersion}` placeholder with the current version or add the corresponding property in your pom.xml_ 67 | 68 | 2. Update the gwt-maven-plugin configuration to support the experimental `JsInterop` feature. 69 | 70 | 71 | org.codehaus.mojo 72 | gwt-maven-plugin 73 | ... 74 | 75 | JS 76 | ... 77 | 78 | 79 | 80 | _**Note**: JsInterop is an experimental flag in GWT-2.7.0 and you need to enable it explicitly. In future versions of GWT it will be enabled by default._ 81 | 82 | 3. Update `TodoList.gwt.xml` module file so that we can use the new gwt library. 83 | 84 | 85 | ... 86 | 87 | ... 88 | 89 | 90 | 4. Update `TodoList.html` 91 | * Configure the `` viewport to handle mobile layouting. 92 | * Import the polyfill ` 101 | 102 | 103 | 104 | 105 | 106 | 107 | 5. Remove `greetServlet` and its mapping in `WEB-INF/web-xml` 108 | 109 | 110 | 111 | 112 | 6. Remove all unnecessary files. 113 | 114 | * Remove the folder and shared folders located in `src/main/java/org/gwtproject/tutorial`. 115 | * Remove `GreetingService.java` and `GreetingServiceAsync.java` from the `client` package. 116 | * Remove the example tests in `src/main/test`. 117 | 118 | 7. Update the **EntryPoint**. 119 | 120 | Replace the content of `TodoList.java` with 121 | 122 | package org.gwtproject.tutorial; 123 | 124 | import com.google.gwt.core.client.EntryPoint; 125 | import com.google.gwt.user.client.ui.RootPanel; 126 | import com.vaadin.polymer.paper.widget.PaperButton; 127 | 128 | public class TodoList implements EntryPoint { 129 | public void onModuleLoad() { 130 | // Use Widget API to Create a 131 | PaperButton button = new PaperButton("Press me!"); 132 | button.setRaised(true); 133 | RootPanel.get().add(button); 134 | 135 | // Use the Element API to create a 136 | PaperButtonElement buttonElement = 137 | Polymer.createElement(PaperButtonElement.TAG); 138 | buttonElement.setTextContent("Click me!"); 139 | Document.get().getBody().appendChild((Element)buttonElement); 140 | } 141 | } 142 | 143 | _**Note**: The example above shows how to add a `PaperButton` element using both the Widgets and Elements API._ 144 | 145 | 8. Run the application again. 146 | 147 | You should see a web page containing a few Material Design buttons. 148 | 149 | _**Tip**: if you get a ClassCastException in the browser’s console, make sure that you’re using the `-XjsInteropMode JS` parameter_. 150 | 151 | ## What's next 152 | 153 | In this lesson we learned how to: 154 | 155 | - Create a new GWT maven project from scratch. 156 | - Run and debug our application in SuperDevMode 157 | - Add external dependencies to our project. 158 | - Configure our project to use the experimental `JsInterop` mode. 159 | - Replace the starter application code with our own. 160 | 161 | We’re now prepared to design the UI of the **TodoList** application. There are two ways we can go about it: using GWT widgets (classic) or the Elements API (modern). 162 | 163 | [Step 2a: Building the User Interface using Widgets](widgets-buildui.html) 164 | 165 | [Step 2b: Building the User Interface using Elements](elements-buildui.html) 166 | 167 | [**DISCLAIMER**](introduction.html#pol-disclaimer) 168 | -------------------------------------------------------------------------------- /docs/elements-applogic.md: -------------------------------------------------------------------------------- 1 | Adding the Application Logic. 2 | === 3 | 4 | Up till now, we’ve designed our UI using `UiBinders` and `Elements`. 5 | 6 | In this section, we’ll learn how to add logic to our UI. We’ll touch on very basic data modelling and how to handle native element events. 7 | 8 | 1. Create the *Add Item dialog* by adding the following markup to the `Main.ui.xml` file: 9 | 10 | 11 | ... 12 | 15 |

Add Item

16 | 18 |
19 | 20 |
21 |
22 | Cancel 23 | OK 25 |
26 |
27 |
28 | 29 | _**Tip**: You can use attributes to quickly define certain polymer actions such as `entry-animation='fade-in-animation'`._ 30 | 31 | 2. Add all the fields defined in the `Main.ui.xml` file to the `Main.java` class. 32 | 33 | @UiField PaperDrawerPanelElement drawerPanel; 34 | @UiField HTMLElement content; 35 | 36 | @UiField PaperDialogElement addItemDialog; 37 | @UiField PaperInputElement titleInput; 38 | @UiField PaperTextareaElement descriptionInput; 39 | @UiField PaperButtonElement confirmAddButton; 40 | 41 | 3. Add a click handler to the floating action button in the `Main` constructor. 42 | 43 | public Main() { 44 | initWidget(ourUiBinder.createAndBindUi(this)); 45 | 46 | addButton.addEventListener("click", new EventListener() { 47 | @Override 48 | public void handleEvent(Event event) { 49 | addItemDialog.open(); 50 | } 51 | }); 52 | } 53 | 54 | _**Note**: Because elements lack methods for handling GWT events, we cannot use `@UiHandler` annotations. Thus we have to configure events in the constructor._ 55 | 56 | 4. Reload the application 57 | 58 | Now you can open the dialog by clicking on the floating action button in the bottom right corner. 59 | 60 | 61 | 62 | 6. Create a `UiBinder` widget for displaying items: `Item.ui.xml` and `Item.java` 63 | 64 | * `Item.ui.xml` 65 | 66 | 69 | 70 |
71 | 84 |
85 |

86 | 87 | Go to Google 88 |

89 |
90 |
91 |
92 | 93 | 94 | * `Item.java`: For simplicity, we will use this class as the item POJO. 95 | 96 | package org.gwtproject.tutorial.client; 97 | 98 | import com.google.gwt.core.shared.GWT; 99 | import com.google.gwt.dom.client.DivElement; 100 | import com.google.gwt.dom.client.Element; 101 | import com.google.gwt.uibinder.client.UiBinder; 102 | import com.google.gwt.uibinder.client.UiField; 103 | import com.vaadin.polymer.elemental.Event; 104 | import com.vaadin.polymer.elemental.EventListener; 105 | import com.vaadin.polymer.paper.element.PaperCheckboxElement; 106 | 107 | public class Item { 108 | 109 | private final DivElement element; 110 | 111 | interface ItemUiBinder extends UiBinder { 112 | } 113 | 114 | private static ItemUiBinder ourUiBinder = GWT.create(ItemUiBinder.class); 115 | 116 | @UiField Element title; 117 | @UiField Element description; 118 | @UiField PaperCheckboxElement done; 119 | 120 | public Item() { 121 | element = ourUiBinder.createAndBindUi(this); 122 | 123 | done.addEventListener("iron-change", new EventListener() { 124 | @Override 125 | public void handleEvent(Event event) { 126 | if (done.getActive()) { 127 | title.addClassName("done"); 128 | } else { 129 | title.removeClassName("done"); 130 | } 131 | } 132 | }); 133 | } 134 | 135 | public String getTitle() { 136 | return title.getInnerText(); 137 | } 138 | public void setTitle(String s) { 139 | title.setInnerText(s); 140 | } 141 | public String getDescription() { 142 | return description.getInnerText(); 143 | } 144 | public void setDescription(String s) { 145 | description.setInnerText(s); 146 | } 147 | public boolean isDone() { 148 | return done.getActive(); 149 | } 150 | public void setDone(boolean b) { 151 | done.setActive(b); 152 | } 153 | public DivElement getElement() { 154 | return element; 155 | } 156 | } 157 | 158 | 159 | 7. Add the logic for creating items when we click the save button. 160 | 161 | ... 162 | private List items = new ArrayList<>(); 163 | 164 | public Main() { 165 | ... 166 | addButton.addEventListener("click", new EventListener() { 167 | public void handleEvent(Event event) { 168 | addItemDialog.open(); 169 | } 170 | }); 171 | 172 | confirmAddButton.addEventListener("click", new EventListener() { 173 | public void handleEvent(Event event) { 174 | if (!titleInput.getValue().isEmpty()) { 175 | addItem(titleInput.getValue(), descriptionInput.getValue()); 176 | // clear text fields 177 | titleInput.setValue(""); 178 | descriptionInput.setValue(""); 179 | } 180 | } 181 | }); 182 | } 183 | 184 | private void addItem(String title, String description) { 185 | Item item = new Item(); 186 | item.setTitle(title); 187 | item.setDescription(description); 188 | content.appendChild(item.getElement()); 189 | items.add(item); 190 | } 191 | ... 192 | 193 | 8. Reload the application 194 | 195 | Now you can add Todo items and mark them as done using checkboxes. 196 | 197 | 198 | 199 | 9. Add the **Clear All** and **Clear Done** menu item handlers in the constructor. 200 | 201 | public Main() { 202 | ... 203 | menuClearAll.addEventListener("click", new EventListener() { 204 | public void handleEvent(Event event) { 205 | closeMenu(); 206 | // remove all child elements 207 | while (content.hasChildNodes()) { 208 | content.removeChild(content.getFirstChild()); 209 | } 210 | } 211 | }); 212 | 213 | menuClearDone.addEventListener("click", new EventListener() { 214 | public void handleEvent(Event event) { 215 | closeMenu(); 216 | 217 | for (Item item : items) { 218 | if (item.isDone()) { 219 | content.removeChild(item.getElement()); 220 | items.remove(item); 221 | } 222 | } 223 | } 224 | }); 225 | } 226 | 227 | private void closeMenu() { 228 | if (drawerPanel.getNarrow()) { 229 | drawerPanel.closeDrawer(); 230 | } 231 | } 232 | 233 | _**Note**: The closeMenu() method is only useful if the application is viewed on a mobile device, or if your browser window is narrow enough for the side menu to collapse. Hence, we use this method to hide the menu after clicking on any menu item._ 234 | 235 | 10. The final `Main.java` should look like this 236 | 237 | package org.gwtproject.tutorial.client; 238 | 239 | import com.google.gwt.core.client.GWT; 240 | import com.google.gwt.uibinder.client.UiBinder; 241 | import com.google.gwt.uibinder.client.UiField; 242 | import com.google.gwt.user.client.ui.Composite; 243 | import com.google.gwt.user.client.ui.HTMLPanel; 244 | import com.vaadin.polymer.elemental.*; 245 | import com.vaadin.polymer.paper.element.*; 246 | 247 | import java.util.ArrayList; 248 | import java.util.List; 249 | 250 | public class Main extends Composite { 251 | interface MainUiBinder extends UiBinder { 252 | } 253 | 254 | private static MainUiBinder ourUiBinder = GWT.create(MainUiBinder.class); 255 | 256 | @UiField PaperDrawerPanelElement drawerPanel; 257 | 258 | @UiField PaperIconItemElement menuClearAll; 259 | @UiField PaperIconItemElement menuClearDone; 260 | 261 | @UiField HTMLElement content; 262 | @UiField PaperFabElement addButton; 263 | 264 | @UiField PaperDialogElement addItemDialog; 265 | @UiField PaperInputElement titleInput; 266 | @UiField PaperTextareaElement descriptionInput; 267 | @UiField PaperButtonElement confirmAddButton; 268 | 269 | private List items = new ArrayList<>(); 270 | 271 | public Main() { 272 | initWidget(ourUiBinder.createAndBindUi(this)); 273 | 274 | addButton.addEventListener("click", new EventListener() { 275 | public void handleEvent(Event event) { 276 | addItemDialog.open(); 277 | } 278 | }); 279 | 280 | confirmAddButton.addEventListener("click", new EventListener() { 281 | public void handleEvent(Event event) { 282 | if (!titleInput.getValue().isEmpty()) { 283 | addItem(titleInput.getValue(), descriptionInput.getValue()); 284 | // clear text fields 285 | titleInput.setValue(""); 286 | descriptionInput.setValue(""); 287 | } 288 | } 289 | }); 290 | 291 | menuClearAll.addEventListener("click", new EventListener() { 292 | public void handleEvent(Event event) { 293 | closeMenu(); 294 | // remove all child elements 295 | while (content.hasChildNodes()) { 296 | content.removeChild(content.getFirstChild()); 297 | } 298 | } 299 | }); 300 | 301 | menuClearDone.addEventListener("click", new EventListener() { 302 | public void handleEvent(Event event) { 303 | closeMenu(); 304 | 305 | for (Item item : items) { 306 | if (item.isDone()) { 307 | content.removeChild(item.getElement()); 308 | items.remove(item); 309 | } 310 | } 311 | } 312 | }); 313 | } 314 | 315 | private void addItem(String title, String description) { 316 | Item item = new Item(); 317 | item.setTitle(title); 318 | item.setDescription(description); 319 | content.appendChild(item.getElement()); 320 | items.add(item); 321 | } 322 | 323 | private void closeMenu() { 324 | if (drawerPanel.getNarrow()) { 325 | drawerPanel.closeDrawer(); 326 | } 327 | } 328 | } 329 | 330 | 11. Reload the application 331 | 332 | * Add several items 333 | * Mark some of them as done 334 | * Click on "Clear Done" menu item 335 | * Click on "Clear All" menu item 336 | 337 | ## Summary 338 | 339 | In this chapter we have learned how to: 340 | 341 | 1. Add more element-based `UiBinder` widgets to our Application. 342 | 2. Add events handlers to Elements. 343 | 3. Use good looking Polymer-based components like Paper dialogs and buttons. 344 | 4. Handle very basic Data Model in GWT. 345 | 346 | [**DISCLAIMER**](introduction.html#pol-disclaimer) 347 | -------------------------------------------------------------------------------- /docs/elements-buildui.md: -------------------------------------------------------------------------------- 1 | # Building the UI 2 | 3 | In this chapter we’ll build a modern looking UI for the **TodoList** application using the [Material Design](http://www.google.es/design/spec/material-design/introduction.html) specifications. We’ll be working with the Vaadin gwt-polymer-elements library, a wrapper for the Polymer Paper Elements collection. 4 | 5 | ## Main screen 6 | 7 | 1. Create the **main screen** of the application. 8 | 9 | We will create a [UiBinder](DevGuideUiBinder.html) screen composed of a java file (`Main.java`) and its visual descriptor (`Main.ui.xml`). 10 | 11 | You can generate these files either by copying the following snippets, or by using the Eclipse GWT plugin. 12 | 13 | * `Main.java` 14 | 15 | package org.gwtproject.tutorial.client; 16 | 17 | import com.google.gwt.core.client.GWT; 18 | import com.google.gwt.uibinder.client.UiBinder; 19 | import com.google.gwt.user.client.ui.Composite; 20 | import com.google.gwt.user.client.ui.HTMLPanel; 21 | 22 | public class Main extends Composite { 23 | interface MainUiBinder extends UiBinder { 24 | } 25 | 26 | private static MainUiBinder ourUiBinder = GWT.create(MainUiBinder.class); 27 | 28 | public Main() { 29 | initWidget(ourUiBinder.createAndBindUi(this)); 30 | } 31 | } 32 | 33 | * `Main.ui.xml` 34 | 35 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 2. Add **menu items**. 44 | 45 | Now we can update the `Main.ui.xml` file by adding menu items. 46 | 47 | 49 | 50 | 51 | 52 | 53 |
Clear All
54 |
55 | 56 | 57 |
Clear Done
58 |
59 | 60 | 61 |
Settings
62 |
63 | 64 | 65 |
About
66 |
67 |
68 |
69 | 70 | _**Note:** Visit the original [polymer elements](https://elements.polymer-project.org/browse?package=paper-elements) documentation to learn and demo each component._ 71 | 72 | 3. Update the **entry point** to use our new screen. 73 | 74 | package org.gwtproject.tutorial.client; 75 | 76 | import com.google.gwt.core.client.EntryPoint; 77 | import com.google.gwt.user.client.ui.RootPanel; 78 | import com.vaadin.polymer.Polymer; 79 | import com.vaadin.polymer.elemental.Function; 80 | 81 | public class TodoList implements EntryPoint { 82 | 83 | public void onModuleLoad() { 84 | // We have to load icon sets before run application 85 | Polymer.importHref(Arrays.asList( 86 | PaperIconItemElement.SRC, 87 | IronIconElement.SRC), new Function() { 88 | public Object call(Object arg) { 89 | // The app is executed when all imports succeed. 90 | startApplication(); 91 | return null; 92 | } 93 | }); 94 | } 95 | 96 | private void startApplication() { 97 | RootPanel.get().add(new Main()); 98 | } 99 | } 100 | 101 | _**Tip**: to facilitate the usage of webcomponents gwt-polymer-elements maintains a couple of static constants: `Element.TAG` and `Element.SRC`, to avoid memorizing tag names and import paths respectively. 102 | 103 | 4. Run the application. 104 | 105 | Reload the page in your browser, and you should see the four menu items. You'll probably notice that icons are missing. We’ll fix that in the next step. 106 | 107 | 108 | 109 | ## Icons and effects 110 | 111 | 1. Import **icon collections**. 112 | 113 | Polymer comes with several icon collections. Before a collection can be used, it has to be imported. In this example we’ll be using the Iron set. In the code below, we use the `Polymer.importHref` utility method, and wait for the set to load before we run the application. 114 | 115 | package org.gwtproject.tutorial.client; 116 | 117 | import com.google.gwt.core.client.EntryPoint; 118 | import com.google.gwt.user.client.ui.RootPanel; 119 | import com.vaadin.polymer.Polymer; 120 | import com.vaadin.polymer.elemental.Function; 121 | 122 | public class TodoList implements EntryPoint { 123 | 124 | public void onModuleLoad() { 125 | // We have to load icon sets before run application 126 | Polymer.importHref(Arrays.asList( 127 | "iron-icons/iron-icons.html", 128 | PaperIconItemElement.SRC, 129 | IronIconElement.SRC), new Function() { 130 | public Object call(Object arg) { 131 | // The app is executed when all imports succeed. 132 | startApplication(); 133 | return null; 134 | } 135 | }); 136 | } 137 | 138 | private void startApplication() { 139 | RootPanel.get().add(new Main()); 140 | } 141 | } 142 | 143 | 2. Reload the application 144 | 145 | You should see all icons in the browser now. 146 | 147 | 148 | 149 | 3. Add a **Ripple** effect 150 | 151 | Feedback when interacting with UI elements is generally considered a positive. If you want, you can read more about Material Design’s philosophy regarding [responsive interaction](http://www.google.com.ua/design/spec/animation/responsive-interaction.html#responsive-interaction-radial-action). 152 | 153 | * Add `` to each item in the `Main.ui.xml` file. 154 | * We need to add a few CSS style properties to the items, so that the ripple effect is constrained within the item area. 155 | 156 | 158 | 159 | 160 | 166 | 167 | 168 |
Clear All
169 | 170 |
171 | 172 | 173 |
Clear Done
174 | 175 |
176 | 177 | 178 |
Settings
179 | 180 |
181 | 182 | 183 |
About
184 | 185 |
186 |
187 |
188 | 189 | 4. Reload the application to see the ripple effect in action. 190 | 191 | Compare click reactions before and after adding `PaperRipple` effects. 192 | 193 | ## Responsive Layout 194 | 195 | 1. Layout the application with a Paper **Draw Panel**. 196 | 197 | The Paper elements collection includes a responsive drawer panel. It’s a layout component that can be used in modern applications to make sure they behave nicely on both desktop and mobile devices. For more information, check out the paper-drawer-panel [demo](https://elements.polymer-project.org/elements/paper-drawer-panel?view=demo:demo/index.html). 198 | 199 | 201 | 202 | 203 | 209 | 210 |
211 | 212 | 213 | 214 | 215 |
Clear All
216 | 217 |
218 | 219 | 220 |
Clear Done
221 | 222 |
223 | 224 | 225 |
Settings
226 | 227 |
228 | 229 | 230 |
About
231 | 232 |
233 |
234 |
235 |
236 | 237 | 238 | 239 | Todo List 240 | 241 | 242 |
243 |
244 |
245 |
246 | 247 | 2. Add the *content panel* 248 | 249 | * Add a container for our todo items. 250 | 251 | 252 | ... 253 |
254 | 255 | 256 | 257 | Todo List 258 | 259 | 260 |
261 | 262 | 263 |
264 | ... 265 | 266 | 267 | 3. Reload the application 268 | 269 | The application should now sport a modern look and be responsive. If you resize the browser window so that its width is below 640px the drawer panel should hide the menu. 270 | 271 | 272 | 273 | ## Styling the App 274 | 275 | Web Components use [Shadow DOM styling](http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-201/) rules for providing scoped styling of the element. Additionally Polymer provides [Shady DOM](https://www.polymer-project.org/1.0/articles/shadydom.html) to deal with browsers not implementing native shadow. Hence Polymer monitors and parses each ` 303 | ... 304 |
305 | 306 | 307 | 308 | Todo List 309 | 310 |
311 | 312 |
313 | ... 314 | 315 | 316 | _**Note**: the `vertical`, `center-justified` and `layout` classes are provided by Polymer._ 317 | 318 | * Add and stylize the **floating action button** 319 | 320 | Material Design applications use the characteristic floating button for the main action. In the Paper elements collection, this button is called [paper-fab][1]. 321 | 322 | 323 | 332 |
333 | ... 334 | 335 |
336 |
337 | 338 | _**Tip**: In order to make Polymer process your style block add the `is="custom-style"` attribute._ 339 | 340 | _**Tip**: Take a look at [paper-fab][1] documentation for available custom styling properties and mixins._ 341 | 342 | [1]: https://elements.polymer-project.org/elements/paper-fab 343 | 344 | ## Summary 345 | 346 | Finally your `Main.gwt.xml` file should look like: 347 | 348 | 350 | 351 | 352 | 374 | 375 |
376 | 377 | 378 | 379 | 380 |
Clear All
381 | 382 |
383 | 384 | 385 |
Clear Done
386 | 387 |
388 | 389 | 390 |
Settings
391 | 392 |
393 | 394 | 395 |
About
396 | 397 |
398 |
399 |
400 |
401 | 402 | 403 | 404 | Todo List 405 | 406 |
407 | 408 | 409 |
410 | 411 | 412 | 413 | 414 | If everything is OK, after reloading your app should look like this: 415 | 416 | 417 | 418 | 419 | ## What's next 420 | 421 | 1. We have learnt how to use `UiBinder` with `Elements`. 422 | 2. We also know how to add 3rd party Web Components to our UI. 423 | 3. We understand the mechanism to import polymer elements like icon collections and use special components like effects. 424 | 3. We can deal with responsive layouts using paper panels and mixing them with conventional html elements in GWT. 425 | 4. We know how to style elements in UiBinder XML files, using Polymer parsers. 426 | 427 | [Step 3: Add logic to the application](elements-applogic.html) 428 | 429 | [**DISCLAIMER**](introduction.html#pol-disclaimer) 430 | -------------------------------------------------------------------------------- /docs/images/todo-list-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manolo/gwt-polymer-todo-list/88f8832d1067d77cfb86ce4f29fcd49fda7af5e5/docs/images/todo-list-01.png -------------------------------------------------------------------------------- /docs/images/todo-list-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manolo/gwt-polymer-todo-list/88f8832d1067d77cfb86ce4f29fcd49fda7af5e5/docs/images/todo-list-02.png -------------------------------------------------------------------------------- /docs/images/todo-list-03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manolo/gwt-polymer-todo-list/88f8832d1067d77cfb86ce4f29fcd49fda7af5e5/docs/images/todo-list-03.png -------------------------------------------------------------------------------- /docs/images/todo-list-04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manolo/gwt-polymer-todo-list/88f8832d1067d77cfb86ce4f29fcd49fda7af5e5/docs/images/todo-list-04.png -------------------------------------------------------------------------------- /docs/images/todo-list-05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manolo/gwt-polymer-todo-list/88f8832d1067d77cfb86ce4f29fcd49fda7af5e5/docs/images/todo-list-05.png -------------------------------------------------------------------------------- /docs/images/todo-list-06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manolo/gwt-polymer-todo-list/88f8832d1067d77cfb86ce4f29fcd49fda7af5e5/docs/images/todo-list-06.png -------------------------------------------------------------------------------- /docs/images/todo-list-07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manolo/gwt-polymer-todo-list/88f8832d1067d77cfb86ce4f29fcd49fda7af5e5/docs/images/todo-list-07.png -------------------------------------------------------------------------------- /docs/images/todo-list-08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manolo/gwt-polymer-todo-list/88f8832d1067d77cfb86ce4f29fcd49fda7af5e5/docs/images/todo-list-08.png -------------------------------------------------------------------------------- /docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Building a modern GWT app using Polymer Elements: 2 | 3 | ## **Disclaimer** : 4 | _This tutorial is based on the usage of three third-party **open-source** libraries, external to, and not managed by, the **gwtproject** organization_: 5 | 6 | * _[**Polymer**][1]: a JavaScript library for building web applications with Web Components. Polymer is owned by **Google Inc**._ 7 | * _[**Polymer Elements**][5]: a collection of widgets built in Polymer. Owned by **Google Inc**._ 8 | * _[**GWT-Polymer-Elements**][3]: a Java wrapper enabling Polymer Elements to be used in GWT projects. Owned by **Vaadin Ltd**._ 9 | 10 | The main goal of the tutorial is to teach our audience the process of creating real GWT projects that use JavaScript widgets and libraries. 11 | 12 | The **gwtproject** is not affiliated with, nor does it endorse, the aforementioned libraries. 13 | 14 | ## Introduction 15 | 16 | In this tutorial, you’ll learn how to write a **TodoList** application using Polymer Web Components. [Web Components][1] define a collection of standards allowing us to bundle markup and styles into custom HTML elements. [Polymer][0] is a JavaScript library designed to make web component development easier. 17 | 18 | In this case, we want to fulfil the [Material Design][2] specification. Therefore, we’ll be using the Vaadin [gwt-polymer-elements][3] library. This library, generated by [gwt-api-generator][4], is a JsInterop wrapper for the Polymer [Iron and Paper][5] elements. 19 | 20 | Before we start, you might want to try out the [TodoList][6] application to see what we are about to build. 21 | 22 | [0]: https://www.polymer-project.org/1.0/ 23 | [1]: https://en.wikipedia.org/wiki/Web_Components 24 | [2]: http://www.google.es/design/spec/material-design/introduction.html 25 | [3]: https://github.com/vaadin/gwt-polymer-elements 26 | [4]: https://github.com/vaadin/gwt-api-generator 27 | [5]: https://elements.polymer-project.org/ 28 | [6]: http://manolo.github.io/gwt-polymer-todo-list/demo/TodoListWidgets.html 29 | 30 | ## The Learning process 31 | 32 | During this build process you’ll learn how to: 33 | 34 | * Create a new Maven project. 35 | * Run your project using `SuperDevMode`. 36 | * Add external libraries to your application. 37 | * Configure the project to use the experimental `JsInterop` mode. 38 | 39 | This application can be built using either widgets or JsInterop elements. The former is the classic approach, while the latter has become the new tendency. Either option will teach you how to: 40 | 41 | * Create new widgets using UiBinder. 42 | * Import and use Polymer Web Components. 43 | * Deal with responsive layouts. 44 | * Style elements using `UiBinder`. 45 | * Add event handlers to UiBinder components. 46 | * Use a basic data model. 47 | 48 | ## What's next 49 | 50 | [Step 1: Create and prepare a new Project](create.html) 51 | -------------------------------------------------------------------------------- /docs/widgets-applogic.md: -------------------------------------------------------------------------------- 1 | Adding the Application Logic. 2 | === 3 | 4 | Up till now, we’ve designed our UI using UiBinders. 5 | 6 | In this section, we’ll learn how to add logic to our UI. We’ll touch on very basic data modelling and how to handle widget events. 7 | 8 | 1. Create the **Add Item dialog** by adding the following markup to the Main.ui.xml file: 9 | 10 | 11 | ... 12 | 15 |

Add Item

16 | 18 |
19 | 20 |
21 |
22 | Cancel 23 | OK 25 |
26 |
27 |
28 | 29 | _**Tip**: You can use attributes to quickly define certain polymer actions such as `entry-animation='fade-in-animation'`._ 30 | 31 | _**Note**: When there are attributes in the component no mapped to a Java method, you can use the `attributes` key, like we do in the `Cancel` and `OK` buttons. Visit [paper-dialog page](https://elements.polymer-project.org/elements/paper-dialog) page and check out API Reference section for more information_ 32 | 33 | 2. Add all the fields defined in the `Main.ui.xml` file to the `Main.java` class. 34 | 35 | @UiField PaperDrawerPanel drawerPanel; 36 | @UiField HTMLPanel content; 37 | 38 | @UiField PaperDialog addItemDialog; 39 | @UiField PaperInput titleInput; 40 | @UiField PaperTextarea descriptionInput; 41 | 42 | 3. Bind the click handler method to the floating action button in the `Main.java` 43 | 44 | @UiHandler("addButton") 45 | protected void onAddButtonClick(ClickEvent e) { 46 | addItemDialog.open(); 47 | } 48 | 49 | 4. Reload the application 50 | 51 | Now you can open the dialog by clicking on the floating action button in the bottom right corner. 52 | 53 | 54 | 55 | 6. Create a `UiBinder` widget for displaying items: `Item.ui.xml` and `Item.java` 56 | 57 | * `Item.ui.xml` 58 | 59 | 63 | 64 | @external .done; 65 | .item .done { 66 | text-decoration: line-through; 67 | } 68 | .title { 69 | padding-left: 20px; 70 | font-size: 150%; 71 | font-weight: normal; 72 | } 73 | 74 | 76 | 78 |
79 |

80 | 81 | Go to Google 82 |

83 |
84 |
85 |
86 |
87 | 88 | * `Item.java`: For simplicity, we will use this class as the item POJO 89 | 90 | package org.gwtproject.tutorial.client; 91 | 92 | import com.google.gwt.core.shared.GWT; 93 | import com.google.gwt.dom.client.Element; 94 | import com.google.gwt.uibinder.client.UiBinder; 95 | import com.google.gwt.uibinder.client.UiField; 96 | import com.google.gwt.uibinder.client.UiHandler; 97 | import com.google.gwt.user.client.ui.Composite; 98 | import com.google.gwt.user.client.ui.HTMLPanel; 99 | import com.vaadin.polymer.iron.widget.event.IronChangeEvent; 100 | import com.vaadin.polymer.paper.widget.PaperCheckbox; 101 | 102 | public class Item extends Composite { 103 | 104 | interface ItemUiBinder extends UiBinder { 105 | } 106 | 107 | private static ItemUiBinder ourUiBinder = GWT.create(ItemUiBinder.class); 108 | 109 | @UiField Element title; 110 | @UiField Element description; 111 | @UiField PaperCheckbox done; 112 | 113 | public Item() { 114 | initWidget(ourUiBinder.createAndBindUi(this)); 115 | } 116 | 117 | @UiHandler("done") 118 | protected void change(IronChangeEvent ev) { 119 | if (done.getActive()) { 120 | title.addClassName("done"); 121 | } else { 122 | title.removeClassName("done"); 123 | } 124 | } 125 | public String getTitle() { 126 | return title.getInnerText(); 127 | } 128 | public void setTitle(String s) { 129 | title.setInnerText(s); 130 | } 131 | public String getDescription() { 132 | return description.getInnerText(); 133 | } 134 | public void setDescription(String s) { 135 | description.setInnerText(s); 136 | } 137 | public boolean isDone() { 138 | return done.getActive(); 139 | } 140 | public void setDone(boolean b) { 141 | done.setActive(b); 142 | } 143 | } 144 | 145 | 146 | 7. Add the logic for creating items when we click the save button. 147 | 148 | At this point your `Main.java` should be like this: 149 | 150 | package org.gwtproject.tutorial.client; 151 | 152 | import com.google.gwt.core.client.GWT; 153 | import com.google.gwt.event.dom.client.ClickEvent; 154 | import com.google.gwt.uibinder.client.UiBinder; 155 | import com.google.gwt.uibinder.client.UiField; 156 | import com.google.gwt.uibinder.client.UiHandler; 157 | import com.google.gwt.user.client.ui.Composite; 158 | import com.google.gwt.user.client.ui.HTMLPanel; 159 | import com.vaadin.polymer.paper.widget.*; 160 | 161 | public class Main extends Composite { 162 | interface MainUiBinder extends UiBinder { 163 | } 164 | 165 | private static MainUiBinder ourUiBinder = GWT.create(MainUiBinder.class); 166 | 167 | @UiField HTMLPanel content; 168 | 169 | @UiField PaperDialog addItemDialog; 170 | @UiField PaperInput titleInput; 171 | @UiField PaperTextarea descriptionInput; 172 | 173 | public Main() { 174 | initWidget(ourUiBinder.createAndBindUi(this)); 175 | } 176 | 177 | @UiHandler("addButton") 178 | protected void onAddButtonClick(ClickEvent e) { 179 | addItemDialog.open(); 180 | } 181 | 182 | @UiHandler("confirmAddButton") 183 | protected void onConfirmAddButtonClick(ClickEvent e) { 184 | if (!titleInput.getValue().isEmpty()) { 185 | addItem(titleInput.getValue(), descriptionInput.getValue()); 186 | // clear text fields 187 | titleInput.setValue(""); 188 | descriptionInput.setValue(""); 189 | } 190 | } 191 | 192 | private void addItem(String title, String description) { 193 | Item item = new Item(); 194 | item.setTitle(title); 195 | item.setDescription(description); 196 | content.add(item); 197 | } 198 | } 199 | 200 | 8. Reload the application 201 | 202 | Now you can add Todo items and mark them as done using checkboxes. 203 | 204 | 205 | 206 | 9. Add the **Clear All** and **Clear Done** menu item handlers 207 | 208 | @UiHandler("menuClearAll") 209 | protected void menuClearAll(ClickEvent e) { 210 | closeMenu(); 211 | content.clear(); 212 | } 213 | 214 | @UiHandler("menuClearDone") 215 | protected void menuClearDone(ClickEvent e) { 216 | closeMenu(); 217 | for (int i = content.getWidgetCount() - 1; i > -1; i--) { 218 | Item item = (Item)content.getWidget(i); 219 | if (item.isDone()) { 220 | content.remove(item); 221 | } 222 | } 223 | } 224 | 225 | private void closeMenu() { 226 | if (drawerPanel.getNarrow()) { 227 | drawerPanel.closeDrawer(); 228 | } 229 | } 230 | 231 | _**Note**: The closeMenu() method is only useful if the application is viewed on a mobile device, or if your browser window is narrow enough for the side menu to collapse. Hence, we use this method to hide the menu after clicking on any menu item._ 232 | 233 | 10. The final `Main.java` should look like this 234 | 235 | package org.gwtproject.tutorial.client; 236 | 237 | import com.google.gwt.core.client.GWT; 238 | import com.google.gwt.event.dom.client.ClickEvent; 239 | import com.google.gwt.uibinder.client.UiBinder; 240 | import com.google.gwt.uibinder.client.UiField; 241 | import com.google.gwt.uibinder.client.UiHandler; 242 | import com.google.gwt.user.client.ui.Composite; 243 | import com.google.gwt.user.client.ui.HTMLPanel; 244 | import com.vaadin.polymer.paper.widget.PaperDialog; 245 | import com.vaadin.polymer.paper.widget.PaperDrawerPanel; 246 | import com.vaadin.polymer.paper.widget.PaperInput; 247 | import com.vaadin.polymer.paper.widget.PaperTextarea; 248 | 249 | public class Main extends Composite { 250 | interface MainUiBinder extends UiBinder { 251 | } 252 | 253 | private static MainUiBinder ourUiBinder = GWT.create(MainUiBinder.class); 254 | 255 | @UiField PaperDrawerPanel drawerPanel; 256 | @UiField HTMLPanel content; 257 | 258 | @UiField PaperDialog addItemDialog; 259 | @UiField PaperInput titleInput; 260 | @UiField PaperTextarea descriptionInput; 261 | 262 | public Main() { 263 | initWidget(ourUiBinder.createAndBindUi(this)); 264 | } 265 | 266 | @UiHandler("addButton") 267 | protected void onAddButtonClick(ClickEvent e) { 268 | addItemDialog.open(); 269 | } 270 | 271 | @UiHandler("confirmAddButton") 272 | protected void onConfirmAddButtonClick(ClickEvent e) { 273 | if (!titleInput.getValue().isEmpty()) { 274 | addItem(titleInput.getValue(), descriptionInput.getValue()); 275 | // clear text fields 276 | titleInput.setValue(""); 277 | descriptionInput.setValue(""); 278 | } 279 | } 280 | 281 | private void addItem(String title, String description) { 282 | Item item = new Item(); 283 | item.setTitle(title); 284 | item.setDescription(description); 285 | content.add(item); 286 | } 287 | 288 | @UiHandler("menuClearAll") 289 | protected void menuClearAll(ClickEvent e) { 290 | closeMenu(); 291 | content.clear(); 292 | } 293 | 294 | private void closeMenu() { 295 | if (drawerPanel.getNarrow()) { 296 | drawerPanel.closeDrawer(); 297 | } 298 | } 299 | 300 | @UiHandler("menuClearDone") 301 | protected void menuClearDone(ClickEvent e) { 302 | closeMenu(); 303 | for (int i = content.getWidgetCount() - 1; i > -1; i--) { 304 | Item item = (Item)content.getWidget(i); 305 | if (item.isDone()) { 306 | content.remove(item); 307 | } 308 | } 309 | } 310 | } 311 | 312 | 11. Reload the application 313 | 314 | * Add several items 315 | * Mark some of them as done 316 | * Click on "Clear Done" menu item 317 | * Click on "Clear All" menu item 318 | 319 | ## Summary 320 | 321 | In this chapter we have learned how to: 322 | 323 | 1. Add more widgets to our Application. 324 | 2. Add event handlers to UiBinder components. 325 | 3. Use good looking Polymer components like dialogs and buttons. 326 | 4. Handle very basic Data Model in GWT. 327 | 328 | [**DISCLAIMER**](introduction.html#pol-disclaimer) 329 | -------------------------------------------------------------------------------- /docs/widgets-buildui.md: -------------------------------------------------------------------------------- 1 | # Building the UI with GWT Widgets. 2 | 3 | 4 | In this chapter we’ll build a modern looking UI for the **TodoList** application using the [Material Design](http://www.google.es/design/spec/material-design/introduction.html) specifications. We’ll be working with the Vaadin gwt-polymer-elements library, a wrapper for the Polymer Paper Elements collection. 5 | 6 | ## Main screen 7 | 8 | 1. Create the **main screen** of the application. 9 | 10 | We will create a [UiBinder](DevGuideUiBinder.html) screen composed of a java file (`Main.java`) and its visual descriptor (`Main.ui.xml`). 11 | 12 | You can generate these files either by copying the following snippets, or by using the Eclipse GWT plugin. 13 | 14 | * `Main.java` 15 | 16 | package org.gwtproject.tutorial; 17 | 18 | import com.google.gwt.core.client.GWT; 19 | import com.google.gwt.uibinder.client.UiBinder; 20 | import com.google.gwt.user.client.ui.Composite; 21 | import com.google.gwt.user.client.ui.HTMLPanel; 22 | 23 | public class Main extends Composite { 24 | interface MainUiBinder extends UiBinder { 25 | } 26 | 27 | private static MainUiBinder ourUiBinder = GWT.create(MainUiBinder.class); 28 | 29 | public Main() { 30 | initWidget(ourUiBinder.createAndBindUi(this)); 31 | } 32 | } 33 | 34 | * `Main.ui.xml` 35 | 36 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 2. Adding **menu items**. 45 | 46 | Now we can update the `Main.ui.xml` file by adding menu items. 47 | 48 | 52 | 53 | 54 | 55 | 56 |
Clear All
57 |
58 | 59 | 60 |
Clear Done
61 |
62 | 63 | 64 |
Settings
65 |
66 | 67 | 68 |
About
69 |
70 |
71 |
72 | 73 | _**Note**: in this step we have added the necessary imports for Paper and Iron packages._ 74 | 75 | _**Tip**: If you are interested on widget details, visit the [Iron](http://vaadin.github.io/gwt-polymer-elements/api/com/vaadin/polymer/iron/widget/package-summary.html) and [Paper](http://vaadin.github.io/gwt-polymer-elements/api/com/vaadin/polymer/paper/widget/package-summary.html) widgets Javadoc_ 76 | 77 | 3. Update the **entry point** to use our new screen. 78 | 79 | package org.gwtproject.tutorial; 80 | 81 | import com.google.gwt.core.client.EntryPoint; 82 | import com.google.gwt.user.client.ui.RootPanel; 83 | 84 | public class TodoList implements EntryPoint { 85 | 86 | public void onModuleLoad() { 87 | RootPanel.get().add(new Main()); 88 | } 89 | } 90 | 91 | 4. Run the application. 92 | 93 | Reload the page in your browser, and you should see the four menu items. You'll probably notice that icons are missing. We’ll fix that in the next step. 94 | 95 | 96 | 97 | ## Icons and effects 98 | 99 | 1. Import **icon collections**. 100 | 101 | Polymer comes with several icon collections. Before a collection can be used, it has to be imported. In this example we’ll be using the Iron set. In the code below, we use the `Polymer.importHref` utility method, and wait for the set to load before we run the application. 102 | 103 | package org.gwtproject.tutorial; 104 | 105 | import com.google.gwt.core.client.EntryPoint; 106 | import com.google.gwt.user.client.ui.RootPanel; 107 | import com.vaadin.polymer.Polymer; 108 | import com.vaadin.polymer.elemental.Function; 109 | 110 | public class TodoList implements EntryPoint { 111 | 112 | public void onModuleLoad() { 113 | // We have to load icon sets before run application 114 | Polymer.importHref("iron-icons/iron-icons.html", new Function() { 115 | public Object call(Object arg) { 116 | // The app is executed when all imports succeed. 117 | startApplication(); 118 | return null; 119 | } 120 | }); 121 | } 122 | 123 | private void startApplication() { 124 | RootPanel.get().add(new Main()); 125 | } 126 | } 127 | 128 | 2. Reload the application 129 | 130 | You should see all icons in the browser now. 131 | 132 | 133 | 134 | 3. Add a **Ripple** effect 135 | 136 | Feedback when interacting with UI elements is generally considered a positive. If you want, you can read more about Material Design’s philosophy regarding [responsive interaction](http://www.google.com.ua/design/spec/animation/responsive-interaction.html#responsive-interaction-radial-action). 137 | 138 | * Add `` to each item in the `Main.ui.xml` file. 139 | * We need to add a few CSS style properties to the items, so that the ripple effect is constrained within the item area. 140 | 141 | 145 | 146 | 147 | paper-icon-item { 148 | position: relative; 149 | overflow: hidden; 150 | } 151 | 152 | 153 | 154 | 155 | 156 |
Clear All
157 | 158 |
159 | 160 | 161 |
Clear Done
162 | 163 |
164 | 165 | 166 |
Settings
167 | 168 |
169 | 170 | 171 |
About
172 | 173 |
174 |
175 |
176 | 177 | 4. Reload the application to see the ripple effect in action. 178 | 179 | Compare click reactions before and after adding `PaperRipple` effects. 180 | 181 | ## Responsive Layout 182 | 183 | 1. Layout the application with a `PaperDrawPanel`. 184 | 185 | The Paper elements collection includes a responsive drawer panel. It’s a layout component that can be used in modern applications to make sure they behave nicely on both desktop and mobile devices. For more information, check out the paper-drawer-panel [demo](https://elements.polymer-project.org/elements/paper-drawer-panel?view=demo:demo/index.html). 186 | 187 | 191 | 192 | 193 | paper-icon-item { 194 | position: relative; 195 | overflow: hidden; 196 | } 197 | 198 | 199 | 200 | 201 |
202 | 203 | 204 | 205 | 206 |
Clear All
207 | 208 |
209 | 210 | 211 |
Clear Done
212 | 213 |
214 | 215 | 216 |
Settings
217 | 218 |
219 | 220 | 221 |
About
222 | 223 |
224 |
225 |
226 |
227 | 228 | 229 | 231 | Todo List 232 | 233 | 234 |
235 |
236 |
237 |
238 | 239 | 2. Add the *content panel* 240 | 241 | * Add a container for our todo items. 242 | 243 | 244 | ... 245 |
246 | 247 | 248 | 250 | Todo List 251 | 252 | 253 | 255 | 256 | 257 |
258 | ... 259 |
260 | 261 | 3. Reload the application 262 | 263 | The application should now sport a modern look and be responsive. If you resize the browser window so that its width is below 640px the drawer panel should hide the menu. 264 | 265 | 266 | 267 | ## Styling the App 268 | 269 | ### Styling with `CssResource` 270 | When using Polymer widgets you can use GWT [GSS](http://www.gwtproject.org/doc/latest/DevGuideGssVsCss.html) parser as usual, and add styles to widgets or elements using the `{}` operator. 271 | 272 | - Change color of the toolbar, style the header text and the content panel: 273 | 274 | 275 | .toolbar { 276 | background: #4285f4 !important; 277 | } 278 | .header { 279 | font-size: 200%; 280 | margin-left: 50px; 281 | background: #4285f4 !important; 282 | } 283 | .content { 284 | padding: 15px; 285 | } 286 | ... 287 | 288 | 289 | ... 290 |
291 | 292 | 293 | 295 | Todo List 296 | 297 | 299 | 300 |
301 | ... 302 |
303 | 304 | _**Note**: the `vertical`, `center-justified` and `layout` classes are provided by Polymer._ 305 | 306 | ### Styling with Polymer 307 | 308 | Web Components use [Shadow DOM styling](http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-201/) rules, providing encapsulated component styles. Additionally, Polymer provides [Shady DOM](https://www.polymer-project.org/1.0/articles/shadydom.html), necessary for browsers not implementing native Shadow DOM. Hence, Polymer monitors and parses each ` 330 |
331 | ... 332 | 334 |
335 | 336 | 337 | _**Tip**: In order to make Polymer process your style block add the `is="custom-style"` attribute._ 338 | 339 | _**Tip**: Take a look at [paper-fab][1] documentation for available custom styling properties and mixins._ 340 | 341 | [1]: https://elements.polymer-project.org/elements/paper-fab 342 | 343 | ## Summary 344 | 345 | Finally your `Main.gwt.xml` file should look like: 346 | 347 | 351 | 352 | 353 | paper-icon-item { 354 | position: relative; 355 | overflow: hidden; 356 | } 357 | .toolbar { 358 | background: #4285f4 !important; 359 | } 360 | .header { 361 | font-size: 200%; 362 | margin-left: 50px; 363 | } 364 | .content { 365 | padding: 15px; 366 | } 367 | 368 | 369 | 370 | 378 | 379 |
380 | 381 | 382 | 383 | 384 |
Clear All
385 | 386 |
387 | 388 | 389 |
Clear Done
390 | 391 |
392 | 393 | 394 |
Settings
395 | 396 |
397 | 398 | 399 |
About
400 | 401 |
402 |
403 |
404 |
405 | 406 | 407 | 409 | Todo List 410 | 411 | 413 | 414 | 416 |
417 |
418 |
419 |
420 | 421 | If everything is OK, after reloading your app should look like this: 422 | 423 | 424 | 425 | ## What's next 426 | 427 | 428 | 429 | 1. We have learnt how to create new widgets using `UiBinder`. 430 | 2. We can add 3rd party widgets to our UI. 431 | 3. We know the mechanism for importing Polymer elements like icon collections, and how to use special components that provide visual effects. 432 | 3. We can work with responsive layouts using Paper panels, and we know how to use them in collaboration with conventional GWT widgets. 433 | 4. We know how to style elements in UiBinder XML files, using GSS or Polymer parsers. 434 | 435 | [Step 3a: Add the event logic to the application](widgets-applogic.html) 436 | 437 | [**DISCLAIMER**](introduction.html#pol-disclaimer) 438 | -------------------------------------------------------------------------------- /elements-todo-list/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 4.0.0 7 | org.gwtproject.tutorial 8 | gwt-polymer-elements-todo 9 | war 10 | 1.9.3.1 11 | GWT Polymer TodoList tutorial App (elements version). 12 | 13 | 14 | 2.8.1 15 | 1.8 16 | 1.8 17 | ${project.version} 18 | UTF-8 19 | 20 | 21 | 22 | 23 | sonatype-snapshots 24 | http://oss.sonatype.org/content/repositories/snapshots 25 | 26 | true 27 | 28 | 29 | false 30 | 31 | 32 | 33 | vaadin-snapshots 34 | https://oss.sonatype.org/content/repositories/vaadin-snapshots/ 35 | 36 | true 37 | 38 | 39 | 40 | google-snapshots 41 | https://oss.sonatype.org/content/repositories/google-snapshots/ 42 | 43 | true 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | com.google.gwt 52 | gwt 53 | ${gwtVersion} 54 | pom 55 | import 56 | 57 | 58 | 59 | 60 | 61 | 62 | com.google.gwt 63 | gwt-user 64 | provided 65 | 66 | 67 | com.google.gwt 68 | gwt-codeserver 69 | provided 70 | 71 | 72 | com.vaadin.polymer 73 | vaadin-gwt-polymer-elements 74 | ${gwtPolymerVersion} 75 | provided 76 | 77 | 78 | 79 | 80 | 81 | 82 | net.ltgt.gwt.maven 83 | gwt-maven-plugin 84 | 1.0-rc-8 85 | 86 | 87 | 88 | compile 89 | 90 | 91 | 92 | 93 | org.gwtproject.tutorial.TodoList 94 | todolistelements 95 | true 96 | 97 | -compileReport 98 | -XcompilerMetrics 99 | 100 | 101 | -bindAddress 102 | 0.0.0.0 103 | 104 | 105 | -bindAddress 106 | 0.0.0.0 107 | -gen 108 | ${project.build.directory}/.generated 109 | 110 | ${project.build.directory}/${project.build.finalName} 111 | compile+runtime 112 | 113 | TodoListElements.html 114 | 115 | 116 | 117 | 118 | maven-resources-plugin 119 | 3.0.2 120 | 121 | 122 | copy-resources 123 | generate-sources 124 | 125 | copy-resources 126 | 127 | 128 | ${project.build.directory}/${project.build.finalName} 129 | 130 | 131 | src/main/webapp 132 | true 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /elements-todo-list/src/main/java/org/gwtproject/tutorial/TodoList.gwt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /elements-todo-list/src/main/java/org/gwtproject/tutorial/client/Item.java: -------------------------------------------------------------------------------- 1 | package org.gwtproject.tutorial.client; 2 | 3 | import com.google.gwt.core.shared.GWT; 4 | import com.google.gwt.dom.client.DivElement; 5 | import com.google.gwt.dom.client.Element; 6 | import com.google.gwt.uibinder.client.UiBinder; 7 | import com.google.gwt.uibinder.client.UiField; 8 | import com.vaadin.polymer.paper.PaperCheckboxElement; 9 | 10 | public class Item { 11 | 12 | private final DivElement element; 13 | 14 | interface ItemUiBinder extends UiBinder { 15 | } 16 | 17 | private static ItemUiBinder ourUiBinder = GWT.create(ItemUiBinder.class); 18 | 19 | @UiField Element title; 20 | @UiField Element description; 21 | @UiField PaperCheckboxElement done; 22 | 23 | public Item() { 24 | element = ourUiBinder.createAndBindUi(this); 25 | 26 | done.addEventListener("iron-change", e -> { 27 | if (done.getActive()) { 28 | title.addClassName("done"); 29 | } else { 30 | title.removeClassName("done"); 31 | } 32 | }); 33 | } 34 | 35 | public String getTitle() { 36 | return title.getInnerText(); 37 | } 38 | 39 | public void setTitle(String s) { 40 | title.setInnerText(s); 41 | } 42 | 43 | public String getDescription() { 44 | return description.getInnerText(); 45 | } 46 | 47 | public void setDescription(String s) { 48 | description.setInnerText(s); 49 | } 50 | 51 | public boolean isDone() { 52 | return done.getActive(); 53 | } 54 | 55 | public void setDone(boolean b) { 56 | done.setActive(b); 57 | } 58 | 59 | public DivElement getElement() { 60 | return element; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /elements-todo-list/src/main/java/org/gwtproject/tutorial/client/Item.ui.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 |
6 | 19 |
20 |

21 | 22 | Go to Google 23 |

24 |
25 |
26 |
27 | 28 | -------------------------------------------------------------------------------- /elements-todo-list/src/main/java/org/gwtproject/tutorial/client/Main.java: -------------------------------------------------------------------------------- 1 | package org.gwtproject.tutorial.client; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import com.google.gwt.core.client.GWT; 7 | import com.google.gwt.dom.client.Element; 8 | import com.google.gwt.uibinder.client.UiBinder; 9 | import com.google.gwt.uibinder.client.UiField; 10 | import com.google.gwt.user.client.ui.Composite; 11 | import com.google.gwt.user.client.ui.HTMLPanel; 12 | import com.vaadin.polymer.Polymer; 13 | import com.vaadin.polymer.elemental.HTMLElement; 14 | import com.vaadin.polymer.paper.PaperButtonElement; 15 | import com.vaadin.polymer.paper.PaperDialogElement; 16 | import com.vaadin.polymer.paper.PaperDrawerPanelElement; 17 | import com.vaadin.polymer.paper.PaperFabElement; 18 | import com.vaadin.polymer.paper.PaperIconItemElement; 19 | import com.vaadin.polymer.paper.PaperInputElement; 20 | import com.vaadin.polymer.paper.PaperTextareaElement; 21 | 22 | public class Main extends Composite { 23 | interface MainUiBinder extends UiBinder { 24 | } 25 | 26 | private static MainUiBinder ourUiBinder = GWT.create(MainUiBinder.class); 27 | 28 | @UiField PaperDrawerPanelElement drawerPanel; 29 | 30 | @UiField PaperIconItemElement menuClearAll; 31 | @UiField PaperIconItemElement menuClearDone; 32 | 33 | @UiField HTMLElement content; 34 | @UiField PaperFabElement addButton; 35 | 36 | @UiField PaperDialogElement addItemDialog; 37 | @UiField PaperInputElement titleInput; 38 | @UiField PaperTextareaElement descriptionInput; 39 | @UiField PaperButtonElement confirmAddButton; 40 | 41 | // Our data base is just an array of items in memory 42 | private List items = new ArrayList<>(); 43 | 44 | public Main() { 45 | initWidget(ourUiBinder.createAndBindUi(this)); 46 | Polymer.endLoading(this.getElement(), (Element)addButton); 47 | 48 | addButton.addEventListener("tap", e -> addItemDialog.open()); 49 | 50 | confirmAddButton.addEventListener("tap", e -> { 51 | if (!titleInput.getValue().isEmpty()) { 52 | addItem(titleInput.getValue(), descriptionInput.getValue()); 53 | // clear text fields 54 | titleInput.setValue(""); 55 | descriptionInput.setValue(""); 56 | } 57 | }); 58 | 59 | menuClearAll.addEventListener("tap", e -> { 60 | closeMenu(); 61 | // remove all child elements 62 | while (content.hasChildNodes()) { 63 | content.removeChild(content.getFirstChild()); 64 | } 65 | }); 66 | 67 | menuClearDone.addEventListener("tap", e -> { 68 | closeMenu(); 69 | for (Item item : items) { 70 | if (item.isDone()) { 71 | content.removeChild(item.getElement()); 72 | items.remove(item); 73 | } 74 | } 75 | }); 76 | } 77 | 78 | private void addItem(String title, String description) { 79 | Item item = new Item(); 80 | item.setTitle(title); 81 | item.setDescription(description); 82 | content.appendChild(item.getElement()); 83 | items.add(item); 84 | } 85 | 86 | private void closeMenu() { 87 | if (drawerPanel.getNarrow()) { 88 | drawerPanel.closeDrawer(); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /elements-todo-list/src/main/java/org/gwtproject/tutorial/client/Main.ui.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 33 | 34 |
35 | 36 | 37 | 38 | 39 |
Clear All
40 | 41 |
42 | 43 | 44 |
Clear Done
45 | 46 |
47 | 48 | 49 |
Settings
50 | 51 |
52 | 53 | 54 |
About
55 | 56 |
57 |
58 |
59 |
60 | 61 | 62 | 63 | Todo List 64 | 65 |
66 | 67 | 68 |
69 | 70 | 71 | 72 |

Add Item

73 | 74 |
75 | 76 |
77 |
78 | Cancel 79 | OK 80 |
81 |
82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /elements-todo-list/src/main/java/org/gwtproject/tutorial/client/TodoList.java: -------------------------------------------------------------------------------- 1 | package org.gwtproject.tutorial.client; 2 | 3 | import java.util.Arrays; 4 | 5 | import com.google.gwt.core.client.EntryPoint; 6 | import com.google.gwt.user.client.ui.RootPanel; 7 | import com.vaadin.polymer.Polymer; 8 | import com.vaadin.polymer.paper.PaperButtonElement; 9 | import com.vaadin.polymer.paper.PaperCheckboxElement; 10 | import com.vaadin.polymer.paper.PaperDialogElement; 11 | import com.vaadin.polymer.paper.PaperDrawerPanelElement; 12 | import com.vaadin.polymer.paper.PaperFabElement; 13 | import com.vaadin.polymer.paper.PaperHeaderPanelElement; 14 | import com.vaadin.polymer.paper.PaperIconButtonElement; 15 | import com.vaadin.polymer.paper.PaperIconItemElement; 16 | import com.vaadin.polymer.paper.PaperInputElement; 17 | import com.vaadin.polymer.paper.PaperRippleElement; 18 | import com.vaadin.polymer.paper.PaperTextareaElement; 19 | import com.vaadin.polymer.paper.PaperToolbarElement; 20 | 21 | public class TodoList implements EntryPoint { 22 | 23 | public void onModuleLoad() { 24 | Polymer.startLoading(); 25 | 26 | Polymer.importHref("paper-styles/demo-pages.html"); 27 | 28 | Polymer.importHref(Arrays.asList( 29 | // We have to load icon sets 30 | "iron-icons/iron-icons.html", 31 | // And we have to load all web components in our application 32 | // before using them as custom elements. 33 | PaperDrawerPanelElement.SRC, 34 | PaperHeaderPanelElement.SRC, 35 | PaperToolbarElement.SRC, 36 | PaperIconItemElement.SRC, 37 | PaperRippleElement.SRC, 38 | PaperIconButtonElement.SRC, 39 | PaperFabElement.SRC, 40 | PaperDialogElement.SRC, 41 | PaperInputElement.SRC, 42 | PaperTextareaElement.SRC, 43 | PaperCheckboxElement.SRC, 44 | PaperButtonElement.SRC), arg -> { 45 | // The app is executed when all imports succeed. 46 | startApplication(); 47 | return null; 48 | }); 49 | } 50 | 51 | private void startApplication() { 52 | RootPanel.get().add(new Main()); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /elements-todo-list/src/main/webapp/TodoList.css: -------------------------------------------------------------------------------- 1 | /** Add css rules here for your application. */ 2 | 3 | 4 | /** Example rules used by the template application (remove for your app) */ 5 | h1 { 6 | font-size: 2em; 7 | font-weight: bold; 8 | color: #777777; 9 | margin: 40px 0px 70px; 10 | text-align: center; 11 | } 12 | 13 | .sendButton { 14 | display: block; 15 | font-size: 16pt; 16 | } 17 | 18 | /** Most GWT widgets already have a style name defined */ 19 | .gwt-DialogBox { 20 | width: 400px; 21 | } 22 | 23 | .dialogVPanel { 24 | margin: 5px; 25 | } 26 | 27 | .serverResponseLabelError { 28 | color: red; 29 | } 30 | 31 | /** Set ids using widget.getElement().setId("idOfElement") */ 32 | #closeButton { 33 | margin: 15px 6px 6px; 34 | } 35 | -------------------------------------------------------------------------------- /elements-todo-list/src/main/webapp/TodoListElements.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | GWT-Polymer TodoList (Elements) 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /elements-todo-list/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | TodoList.html 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /elements-todo-list/src/main/webapp/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manolo/gwt-polymer-todo-list/88f8832d1067d77cfb86ce4f29fcd49fda7af5e5/elements-todo-list/src/main/webapp/favicon.ico -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.gwtproject.tutorial 8 | gwt-polymer-todo-list 9 | pom 10 | 1.9.3.1 11 | 12 | 13 | widgets-todo-list 14 | elements-todo-list 15 | 16 | 17 | 18 | 19 | 20 | maven-antrun-plugin 21 | 22 | 23 | process-resources 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | run 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /widgets-todo-list/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.gwtproject.tutorial 7 | gwt-polymer-widgets-todo 8 | war 9 | 1.9.3.1 10 | GWT Polymer TodoList tutorial App (widgets version). 11 | 12 | 13 | 2.8.1 14 | ${project.version} 15 | 1.8 16 | 1.8 17 | UTF-8 18 | 19 | 20 | 21 | 22 | sonatype-snapshots 23 | http://oss.sonatype.org/content/repositories/snapshots 24 | 25 | true 26 | 27 | 28 | false 29 | 30 | 31 | 32 | vaadin-snapshots 33 | https://oss.sonatype.org/content/repositories/vaadin-snapshots/ 34 | 35 | true 36 | 37 | 38 | 39 | google-snapshots 40 | https://oss.sonatype.org/content/repositories/google-snapshots/ 41 | 42 | true 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | com.google.gwt 51 | gwt 52 | ${gwtVersion} 53 | pom 54 | import 55 | 56 | 57 | 58 | 59 | 60 | 61 | com.google.gwt 62 | gwt-user 63 | provided 64 | 65 | 66 | com.google.gwt 67 | gwt-codeserver 68 | provided 69 | 70 | 71 | com.vaadin.polymer 72 | vaadin-gwt-polymer-elements 73 | ${gwtPolymerVersion} 74 | provided 75 | 76 | 77 | 78 | 79 | 80 | 81 | net.ltgt.gwt.maven 82 | gwt-maven-plugin 83 | 1.0-rc-8 84 | 85 | 86 | 87 | compile 88 | 89 | 90 | 91 | 92 | org.gwtproject.tutorial.TodoList 93 | todolistwidgets 94 | true 95 | 96 | -compileReport 97 | -XcompilerMetrics 98 | 99 | 100 | -bindAddress 101 | 0.0.0.0 102 | 103 | 104 | -bindAddress 105 | 0.0.0.0 106 | -gen 107 | ${project.build.directory}/.generated 108 | 109 | ${project.build.directory}/${project.build.finalName} 110 | compile+runtime 111 | 112 | TodoListElements.html 113 | 114 | 115 | 116 | 117 | maven-resources-plugin 118 | 3.0.2 119 | 120 | 121 | copy-resources 122 | generate-sources 123 | 124 | copy-resources 125 | 126 | 127 | ${project.build.directory}/${project.build.finalName} 128 | 129 | 130 | src/main/webapp 131 | true 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /widgets-todo-list/src/main/java/org/gwtproject/tutorial/TodoList.gwt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /widgets-todo-list/src/main/java/org/gwtproject/tutorial/client/Dialogs.java: -------------------------------------------------------------------------------- 1 | package org.gwtproject.tutorial.client; 2 | 3 | import com.google.gwt.core.shared.GWT; 4 | import com.google.gwt.dom.client.DivElement; 5 | import com.google.gwt.dom.client.Element; 6 | import com.google.gwt.event.dom.client.ClickEvent; 7 | import com.google.gwt.uibinder.client.UiBinder; 8 | import com.google.gwt.uibinder.client.UiField; 9 | import com.google.gwt.uibinder.client.UiHandler; 10 | import com.google.gwt.user.client.ui.Composite; 11 | import com.google.gwt.user.client.ui.HTMLPanel; 12 | import com.google.gwt.user.client.ui.Label; 13 | import com.google.gwt.user.client.ui.Widget; 14 | import com.vaadin.polymer.elemental.Function; 15 | import com.vaadin.polymer.paper.widget.PaperButton; 16 | import com.vaadin.polymer.paper.widget.PaperDialog; 17 | 18 | public class Dialogs extends Composite { 19 | 20 | public static DialogsUiBinder getOurUiBinder() { 21 | return ourUiBinder; 22 | } 23 | 24 | public static void setOurUiBinder(DialogsUiBinder ourUiBinder) { 25 | Dialogs.ourUiBinder = ourUiBinder; 26 | } 27 | 28 | interface DialogsUiBinder extends UiBinder { 29 | } 30 | 31 | private static DialogsUiBinder ourUiBinder = GWT.create(DialogsUiBinder.class); 32 | 33 | public Dialogs() { 34 | initWidget(ourUiBinder.createAndBindUi(this)); 35 | } 36 | 37 | @UiField PaperDialog alert; 38 | @UiField DivElement alertContent; 39 | @UiField PaperButton alertClose; 40 | @UiHandler("alertClose") 41 | protected void alertClose(ClickEvent e) { 42 | alert.close(); 43 | } 44 | 45 | @UiField PaperDialog confirm; 46 | @UiField Element confirmCaption; 47 | @UiField HTMLPanel confirmContent; 48 | @UiField PaperButton confirmCancel; 49 | @UiField PaperButton confirmOk; 50 | @UiHandler("confirmCancel") 51 | protected void confirmCancel(ClickEvent e) { 52 | confirm.close(); 53 | } 54 | @UiHandler("confirmOk") 55 | protected void confirmOk(ClickEvent e) { 56 | if (okFunction != null) { 57 | okFunction.call(null); 58 | } 59 | confirm.close(); 60 | } 61 | 62 | private Function okFunction; 63 | 64 | public void confirm(String message, Function fnc) { 65 | confirm("Confirm", new Label(message), fnc); 66 | } 67 | 68 | public void alert(String message) { 69 | alertContent.setInnerText(message); 70 | alert.open(); 71 | } 72 | 73 | public void confirm(String header, Widget content, Function fnc) { 74 | okFunction = fnc; 75 | confirmCaption.setInnerText(header); 76 | confirmContent.clear(); 77 | confirmContent.add(content); 78 | confirm.open(); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /widgets-todo-list/src/main/java/org/gwtproject/tutorial/client/Dialogs.ui.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 10 | 11 | 12 |

Alert

13 |
14 |
15 |
16 | OK 17 |
18 |
19 | 20 | 21 |

Confirm

22 | 23 |
24 | Cancel 25 | OK 26 |
27 |
28 |
29 |
30 | -------------------------------------------------------------------------------- /widgets-todo-list/src/main/java/org/gwtproject/tutorial/client/Item.java: -------------------------------------------------------------------------------- 1 | package org.gwtproject.tutorial.client; 2 | 3 | import com.google.gwt.core.shared.GWT; 4 | import com.google.gwt.dom.client.Element; 5 | import com.google.gwt.uibinder.client.UiBinder; 6 | import com.google.gwt.uibinder.client.UiField; 7 | import com.google.gwt.uibinder.client.UiHandler; 8 | import com.google.gwt.user.client.ui.Composite; 9 | import com.google.gwt.user.client.ui.HTMLPanel; 10 | import com.vaadin.polymer.iron.widget.event.IronChangeEvent; 11 | import com.vaadin.polymer.paper.widget.PaperCheckbox; 12 | 13 | public class Item extends Composite { 14 | 15 | public static ItemUiBinder getOurUiBinder() { 16 | return ourUiBinder; 17 | } 18 | 19 | public static void setOurUiBinder(ItemUiBinder ourUiBinder) { 20 | Item.ourUiBinder = ourUiBinder; 21 | } 22 | 23 | interface ItemUiBinder extends UiBinder { 24 | } 25 | 26 | private static ItemUiBinder ourUiBinder = GWT.create(ItemUiBinder.class); 27 | 28 | @UiField Element title; 29 | @UiField Element description; 30 | @UiField PaperCheckbox check; 31 | 32 | public Item() { 33 | initWidget(ourUiBinder.createAndBindUi(this)); 34 | } 35 | 36 | @UiHandler("check") 37 | protected void change(IronChangeEvent ev) { 38 | if (check.getActive()) { 39 | title.addClassName("done"); 40 | } else { 41 | title.removeClassName("done"); 42 | } 43 | } 44 | 45 | public String getTitle() { 46 | return title.getInnerText(); 47 | } 48 | 49 | public void setTitle(String s) { 50 | title.setInnerText(s); 51 | } 52 | 53 | public String getDescription() { 54 | return description.getInnerText(); 55 | } 56 | 57 | public void setDescription(String s) { 58 | description.setInnerText(s); 59 | } 60 | 61 | public boolean getCheck() { 62 | return check.getActive(); 63 | } 64 | 65 | public void setCheck(boolean b) { 66 | check.setActive(b); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /widgets-todo-list/src/main/java/org/gwtproject/tutorial/client/Item.ui.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | @external .done; 9 | .item .done { 10 | text-decoration: line-through; 11 | } 12 | 13 | .item > div { 14 | padding: 8px 15px 8px 15px !important; 15 | margin-bottom: 10px !important; 16 | } 17 | .item h4 { 18 | margin: 0px; 19 | } 20 | .title { 21 | padding-left: 20px; 22 | font-size: 150%; 23 | font-weight: normal; 24 | } 25 | .description { 26 | margin-top: 15px; 27 | padding-left: 40px; 28 | } 29 | 30 | 31 | 33 |
34 |

35 | 36 | Go to Google 37 |

38 |
39 |
40 |
41 |
42 | -------------------------------------------------------------------------------- /widgets-todo-list/src/main/java/org/gwtproject/tutorial/client/Main.java: -------------------------------------------------------------------------------- 1 | package org.gwtproject.tutorial.client; 2 | 3 | import com.google.gwt.core.shared.GWT; 4 | import com.google.gwt.event.dom.client.ClickEvent; 5 | import com.google.gwt.uibinder.client.UiBinder; 6 | import com.google.gwt.uibinder.client.UiField; 7 | import com.google.gwt.uibinder.client.UiHandler; 8 | import com.google.gwt.user.client.ui.Composite; 9 | import com.google.gwt.user.client.ui.HTMLPanel; 10 | import com.vaadin.polymer.Polymer; 11 | import com.vaadin.polymer.PolymerWidget.TapEvent; 12 | import com.vaadin.polymer.paper.widget.PaperButton; 13 | import com.vaadin.polymer.paper.widget.PaperDialog; 14 | import com.vaadin.polymer.paper.widget.PaperDrawerPanel; 15 | import com.vaadin.polymer.paper.widget.PaperFab; 16 | import com.vaadin.polymer.paper.widget.PaperIconButton; 17 | import com.vaadin.polymer.paper.widget.PaperIconItem; 18 | import com.vaadin.polymer.paper.widget.PaperInput; 19 | import com.vaadin.polymer.paper.widget.PaperTextarea; 20 | 21 | public class Main extends Composite { 22 | 23 | interface MainUiBinder extends UiBinder { 24 | } 25 | 26 | private static MainUiBinder uiBinder = GWT.create(MainUiBinder.class); 27 | 28 | @UiField PaperDrawerPanel drawerPanel; 29 | @UiField HTMLPanel content; 30 | @UiField PaperIconButton menu; 31 | @UiField Dialogs dialogs; 32 | 33 | public Main() { 34 | initWidget(uiBinder.createAndBindUi(this)); 35 | Polymer.endLoading(this.getElement(), addButton.getElement()); 36 | } 37 | 38 | @UiField PaperFab addButton; 39 | @UiHandler("addButton") 40 | protected void onAddButtonClick(TapEvent e) { 41 | addItemDialog.open(); 42 | } 43 | 44 | @UiField PaperDialog addItemDialog; 45 | @UiField PaperInput titleInput; 46 | @UiField PaperTextarea descriptionInput; 47 | @UiField PaperButton confirmAddButton; 48 | @UiHandler("confirmAddButton") 49 | protected void onConfirmAddButtonTap(TapEvent e) { 50 | if (!titleInput.getValue().isEmpty()) { 51 | addItem(titleInput.getValue(), descriptionInput.getValue()); 52 | // clear text fields 53 | titleInput.setValue(""); 54 | descriptionInput.setValue(""); 55 | } 56 | } 57 | 58 | @UiField PaperIconItem menuClearAll; 59 | @UiHandler("menuClearAll") 60 | protected void menuClearAll(TapEvent e) { 61 | closeMenu(); 62 | if (content.getWidgetCount() > 0) { 63 | dialogs.confirm("Do you really want to remove all Items in the list?", arg -> { 64 | content.clear(); 65 | return null; 66 | }); 67 | } 68 | } 69 | 70 | @UiField PaperIconItem menuClearDone; 71 | @UiHandler("menuClearDone") 72 | protected void menuClearDone(TapEvent e) { 73 | closeMenu(); 74 | for (int i = content.getWidgetCount() - 1; i > -1; i--) { 75 | Item item = (Item)content.getWidget(i); 76 | if (item.getCheck()) { 77 | content.remove(item); 78 | } 79 | } 80 | } 81 | 82 | @UiField PaperIconItem menuSettings; 83 | @UiField PaperIconItem menuAbout; 84 | @UiHandler({"menuSettings", "menuAbout"}) 85 | protected void norImplemented(ClickEvent e) { 86 | closeMenu(); 87 | dialogs.alert("Not implemented yet"); 88 | } 89 | 90 | private void closeMenu() { 91 | if (drawerPanel.getNarrow()) { 92 | drawerPanel.closeDrawer(); 93 | } 94 | } 95 | 96 | private void addItem(String title, String description) { 97 | Item i = new Item(); 98 | i.setTitle(title); 99 | i.setDescription(description); 100 | content.add(i); 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /widgets-todo-list/src/main/java/org/gwtproject/tutorial/client/Main.ui.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | paper-icon-item { 10 | position: relative; 11 | overflow: hidden; 12 | } 13 | .toolbar { 14 | background: #4285f4 !important; 15 | } 16 | .header { 17 | font-size: 200%; 18 | margin-left: 50px; 19 | } 20 | .content { 21 | padding: 15px; 22 | } 23 | .dialog { 24 | min-width: 40%; 25 | } 26 | 27 | 28 | 36 | 37 |
38 | 39 | 40 | 41 | 42 |
Clear All
43 | 44 |
45 | 46 | 47 |
Clear Done
48 | 49 |
50 | 51 | 52 |
Settings
53 | 54 |
55 | 56 | 57 |
About
58 | 59 |
60 |
61 |
62 |
63 | 64 | 65 | 67 | Todo List 68 | 69 | 71 | 72 | 74 |
75 |
76 | 77 | 80 |

Add Item

81 | 84 |
85 | 87 |
88 |
89 | Cancel 90 | OK 92 |
93 |
94 | 95 | 96 | 97 |
98 |
99 | -------------------------------------------------------------------------------- /widgets-todo-list/src/main/java/org/gwtproject/tutorial/client/TodoList.java: -------------------------------------------------------------------------------- 1 | package org.gwtproject.tutorial.client; 2 | 3 | import java.util.Arrays; 4 | 5 | import com.google.gwt.core.client.EntryPoint; 6 | import com.google.gwt.user.client.ui.RootPanel; 7 | import com.vaadin.polymer.Polymer; 8 | 9 | public class TodoList implements EntryPoint { 10 | 11 | public void onModuleLoad() { 12 | // Show a loading message 13 | Polymer.startLoading(); 14 | 15 | Polymer.importHref(Arrays.asList( 16 | // Paper applications must always import paper-styles 17 | "paper-styles", 18 | // Styles for paper examples, we use it for this app as well 19 | "paper-styles/demo-pages.html", 20 | // We have to load icon sets before run Application 21 | "iron-icons/iron-icons.html", 22 | "iron-icons/communication-icons.html", 23 | "neon-animation/neon-animations.html" 24 | )); 25 | 26 | Polymer.whenReady(o -> { 27 | // The app is executed when all imports succeed. 28 | startApplication(); 29 | return null; 30 | }); 31 | } 32 | 33 | private void startApplication() { 34 | RootPanel.get().add(new Main()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /widgets-todo-list/src/main/webapp/TodoListWidgets.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | GWT-Polymer TodoList (Widgets) 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | loading... 17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /widgets-todo-list/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | --------------------------------------------------------------------------------