Solution 6: Drag and Drop 169
Total Page:16
File Type:pdf, Size:1020Kb
06_0132344815_ch06.qxd 10/16/07 11:41 AM Page 167 SolutionSolution 1: Drag and Drop 167 6 Drag and Drop The ultimate in user interactivity, drag and drop is taken for granted in desktop appli- cations but is a litmus test of sorts for web applications: If you can easily implement drag and drop with your web application framework, then you know you’ve got something special. Until now, drag and drop for web applications has, for the most part, been limited to specialized JavaScript frameworks such as Script.aculo.us and Rico.1 No more. With the advent of GWT, we have drag-and-drop capabilities in a Java-based web applica- tion framework. Although GWT does not explicitly support drag and drop (drag and drop is an anticipated feature in the future), it provides us with all the necessary ingre- dients to make our own drag-and-drop module. In this solution, we explore drag-and-drop implementation with GWT. We implement drag and drop in a module of its own so that you can easily incorporate drag and drop into your applications. Stuff You’re Going to Learn This solution explores the following aspects of GWT: • Implementing composite widgets with the Composite class (page 174) • Removing widgets from panels (page 169) • Changing cursors for widgets with CSS styles (page 200) • Implementing a GWT module (page 182) • Adding multiple listeners to a widget (page 186) • Using the AbsolutePanel class to place widgets by pixel location (page 211) • Capturing and releasing events for a specific widget (page 191) • Using an event preview to inhibit browser reactions to events (page 196) 1 See http://www.script.aculo.us and http://openrico.org for more information about Script.aculo.us and Rico, respectively. 06_0132344815_ch06.qxd 10/16/07 11:41 AM Page 168 168 Google Web Toolkit Solutions See Solution 1 and Solution 2 for more in-depth discussions of implementing GWT modules and implementing composite widgets, respectively. The Drag-and-Drop Example Application Our discussion of drag and drop (dnd) starts with a sample application that uses our drag-and-drop module. Then we peel back the layers of the drag-and-drop onion to reveal the underlying implementation. Figure 6.1 shows the drag-and-drop example application in action. The application contains iPods and Zunes that can be dragged into their respective shopping carts. When you start dragging a music player, the cursor changes to the pointer cursor to indicate that a drag is underway, just in case the actual movement of the music player is not enough evidence of that fact. Figure 6.1 The drag-and-drop example application 06_0132344815_ch06.qxd 10/16/07 11:41 AM Page 169 Solution 6: Drag and Drop 169 If a user drags a music player, which in dnd parlance is known as a drag source, over its shopping cart (referred to as a drop target), two things happen: We once again change the cursor, this time to a move cursor, to indicate that a drop is acceptable for this drop target (known as a drag-over effect), and we change the border of the drop Solution 6: Drag and Drop target (known as a drag-under effect). If the user subsequently releases the mouse while the drag source is over the drop target, we remove the drag source from the page and update the drop target to reflect the fact that it now contains the music player that was dropped. If the user starts dragging a music player and then decides against dropping it on its shopping cart panel, we scoot the music player back to its original position, as illus- trated in Figure 6.2. This is standard drag-and-drop behavior. Figure 6.2 Drag sources snap back when dropped outside a drop target Finally, notice that we have two drop targets: one for iPods and another for Zunes. Users cannot drag an iPod into the Zune shopping cart, or vice versa. If they try to do so, the cursor changes to the no-drop cursor when the music player enters the forbid- den shopping cart, as shown in Figure 6.3. When a user drops a music player over a forbidden shopping cart, the music player moves back to its original position, just as it does when dropped outside any drop target. 06_0132344815_ch06.qxd 10/16/07 11:41 AM Page 170 170 Google Web Toolkit Solutions Figure 6.3 Disallowing drops in drop targets Our drag-and-drop application uses a drag-and-drop module. We discuss that module in detail in “Drag and Drop Implementation in a GWT Module” on page 182, but for now let’s see what’s involved in using that module. The Drag-and-Drop Module The drag-and-drop application and its associated files and directories are shown in Figure 6.4. 06_0132344815_ch06.qxd 10/16/07 11:41 AM Page 171 Solution 6: Drag and Drop 171 Solution 6: Drag and Drop Figure 6.4 The drag-and-drop application’s files and directories The application is made up primarily of five things: Java source files; images; a CSS file; a configuration file; and an HTML page. In Solution 1, we showed you how to use custom widgets that were packaged in a module. For the drag-and-drop application, we employ the same technique—a two-step process—to use the drag-and-drop module: • Inherit the module with an inherits element in the configuration file. • Include the module’s JAR file in our application’s classpath. We showed you how to include GWT Solutions Components module in your applica- tion’s classpath in “Custom Widget Use” (page 40), so we don’t cover that ground again, but we do show you how we inherit the drag-and-drop module in the applica- tion’s configuration file. 06_0132344815_ch06.qxd 10/16/07 11:41 AM Page 172 172 Google Web Toolkit Solutions Inheriting the Drag-and-Drop Module in an Application’s Configuration File The XML configuration file for our application is shown in Listing 6.1. Listing 6.1 com/gwtsolutions/DragAndDrop.gwt.xml 1.<module> 2. 3. <!— Inherit the core Web Toolkit stuff. —> 4. <inherits name=’com.google.gwt.user.User’/> 5. 6. <!— Inherit the I18N stuff. —> 7. <inherits name=”com.google.gwt.i18n.I18N”/> 8. 9. <!— Inherit the drag and drop stuff. —> 10. <inherits name=’com.gwtsolutions.components.Components’/> 11. <inherits name=’com.gwtsolutions.components.client.ui.Dnd’/> 12. 13. <!— Include CSS stylesheet. —> 14. <stylesheet src=”styles.css”/> 15. 16. <!— Specify the app entry point class. —> 17. <entry-point class=’com.gwtsolutions.client.DragAndDrop’/> 18. 19.</module> The drag-and-drop application uses GWT internationalization, so we inherit GWT’s I18N module in addition to the User module. The drag-and-drop module resides in the GWT Solutions Components module, so we inherit both of those modules in our application’s configuration file. The configuration file also includes its CSS stylesheet in the configuration file. We could have included the stylesheet with a standard link element in the application’s HTML page, but including stylesheets in GWT configuration files is a more reusable solution because users can reuse your stylesheet along with your module. No one’s ever going to reuse our application’s module, but just the same, we prefer including stylesheets in configuration files to HTML pages in general. Finally, we specify the entry point class for our application, com.gwtsolutions.client. DragAndDrop. Now that we’ve seen how the drag-and-drop application uses the drag-and-drop mod- ule, let’s look at the code for the application. We revisit the drag-and-drop module in “Drag and Drop Implementation in a GWT Module” on page 182, where we look at the module’s implementation. 06_0132344815_ch06.qxd 10/16/07 11:41 AM Page 173 Solution 6: Drag and Drop 173 Implementation of the Drag-and-Drop Application Listing 6.2 shows the drag-and-drop application’s class. Solution 6: Drag and Drop Listing 6.2 com.gwtsolutions.client.DragAndDrop 20.package com.gwtsolutions.client; 21. 22.import com.google.gwt.core.client.EntryPoint; 23.import com.google.gwt.core.client.GWT; 24.import com.google.gwt.user.client.ui.AbsolutePanel; 25.import com.google.gwt.user.client.ui.RootPanel; 26. 27.public class DragAndDrop implements EntryPoint { 28. public void onModuleLoad() { 29. DragAndDropConstants constants = 30. (DragAndDropConstants) GWT 31. .create(DragAndDropConstants.class); 32. 33. final AbsolutePanel ap = new AbsolutePanel(); 34. 35. ap.add(new IpodDropTarget(new ShoppingCartPanel(constants 36. .iPodsOnly())), 125, 10); 37. 38. ap.add(new ZuneDropTarget(new ShoppingCartPanel(constants 39. .zunesOnly())), 125, 260); 40. 41. final MusicPlayer blackIpod = 42. new MusicPlayer(“images/ipod-nano-black.jpg”, 43. constants.blackIPodInfo()); 44. 45. final MusicPlayer blackZune = 46. new MusicPlayer(“images/zune-black.jpg”, constants 47. .blackZuneInfo()); 48. 49. final MusicPlayer silverIpod = 50. new MusicPlayer(“images/ipod-nano-silver.jpg”, 51. constants.silverIPodInfo()); 52. 53. final MusicPlayer brownZune = 54. new MusicPlayer(“images/zune-brown.jpg”, constants 55. .brownZuneInfo()); 56. 57. ap.add(new MusicPlayerDragSource(blackIpod), 10, 20); continues 06_0132344815_ch06.qxd 10/16/07 11:41 AM Page 174 174 Google Web Toolkit Solutions Listing 6.2 com.gwtsolutions.client.DragAndDrop continued 58. ap.add(new MusicPlayerDragSource(brownZune), 10, 120); 59. ap.add(new MusicPlayerDragSource(silverIpod), 10, 200); 60. ap.add(new MusicPlayerDragSource(blackZune), 10, 300); 61. 62. ap.addStyleName(“dragPanel”); 63. RootPanel.get().add(ap); 64. } 65.} The preceding code is straightforward. We create an absolute panel, to which we add two shopping cart panels, each wrapped in a drop target.