How to Create a Swing CRUD Application on NetBeans Platform 6

June 10, 2018 | Author: Carlos Espinoza | Category: Net Beans, Databases, Method (Computer Programming), Library (Computing), Modular Programming


Comments



Description

How to Create a Swing CRUD Application on NetBeans Platform 6.8      0 inShare Submitted by Geertjan Wielenga on Tue, 2009/12/08 - 2:08pm Ads by DZone This article shows you how to integrate a Java DB database into a NetBeans Platform application. We start by exploring a Java DB database, from which we create entity classes. Next, we wrap the entity classes into a module, together with modules for the related JPA JARS. Note: These instructions are not applicable to Java DB only. Rather, they are relevant to any relational database, such as Oracle or MySQL. Several applications on the NetBeans Platform, many of which are listed here, use these databases too. Java DB was chosen for this article because it is easiest to get started with, since it comes with the JDK. Once the above modules are part of our application, we create a new module that provides the user interface for our application. The new module gives the user a tree hierarchy showing data from the database. We then create another module that lets the user edit the data displayed by the first module. By separating the viewer from the editor in distinct modules, we will enable the user to install a different editor for the same viewer, since different editors could be created by external vendors, some commercially and some for free. It is this flexibility that the modular architecture of the NetBeans Platform makes possible. When we have a module for our editor, we begin adding CRUD functionality. First, the "R", standing for "Read", is handled by the viewer described above. Next, the "U" for "Update" is handled, followed by the "C" for "Create", and the "D" for "Delete". At the end of the article, you will have learned about a range of NetBeans Platform features that help you in creating applications of this kind. For example, you will have learned about the UndoRedo.Manager and the ExplorerManager, as well as NetBeans Platform Swing components, such as TopComponent and BeanTreeView. Contents   Setting Up the Application Integrating the Database o Creating Entity Classes from a Database o Wrapping the Entity Class JAR in a Module  Creating Other Related Modules Designing the User Interface Setting Dependencies Running the Prototype Integrating CRUD Functionality o Read o Update o Create o Delete o o o o The application you create in this article will look as follows: Source code: http://kenai.com/projects/nbcustomermanager Once you're at the stage shown above, you can simply download a NetBeans module that provides Office LAF support (described here), add it to your application, and then when you redeploy the application, you will see this: Note: It is advisable to watch the screencast series Top 10 NetBeans APIs before beginning to work on this article. Many of the concepts addressed in this article are discussed in more detail within the screencast series. Setting up the Application Let's start by creating a new NetBeans Platform application. 1. Choose File > New Project (Ctrl+Shift+N). Under Categories, select NetBeans Modules. Under Projects, select NetBeans Platform Application. Click Next. 2. In the Name and Location panel, type DBManager in the Project Name field. Click Finish. The IDE creates the DBManager project. The project is a container for all the other modules you will create. Run the application and notice that you have quite a few features out of the box already. Open some of the windows, undock them, and get to know the basic components that the NetBeans Platform provides without you doing any work whatsoever: Integrating the Database In order to integrate the database, you need to create entity classes from your database and integrate those entity classes, together with their related JARs, into modules that are part of your NetBeans Platform application. Creating the Entity Classes In this section, you generate entity classes from a selected database. In the case of MySQL. Here we choose "Customer". and then "Discount Code" is added automatically. choose File | New Project. 2. see Connecting to a MySQL Database. For purposes of this example. In the Projects window. . In the IDE. followed by Persistence | Entity Classes from Database. 3. since there is a relationship between these two tables. followed by Java | Java Class Library to create a new library project named CustomerLibrary. right-click the library project and choose File | New File. use any database you like and adapt the steps that follow to your particular use case. select your database and the tables you need. use the Services window to connect to the sample database that is included with NetBeans IDE: Note: Alternatively. In the wizard.1. 4. which can be any of the available options. Specify "demo" as the name of the package where the entity classes will be generated. . we'll choose EclipseLink: 5. Specify the persistence strategy. Here. since we need to choose something. among other things. look at the generated code and notice that. as well as entity classes for each of your tables: 7. Click Finish. Build the Java Library and you will have a JAR file in the library project's "dist" folder.6. Once you have completed this step. which you can view in the Files window: . you now have a persistence.xml file in a folder called META-INF. While that keeps it simple. it also makes it a fairly useless example of using the platform in practice.assert EventQueue. One approach is to register actions in the layer file which then enables you to add an attribute to the layer entry.public void actionPerformed(AE ev) { 07.} 06.isEventThread().Craig Ringer replied on Wed. 2009/12/09 .// setup inside AWT thread. 04. as such concurrency issues are crucual when doing database work. 2009/12/09 . That will be fixed.public MyAction(MyContext c) { 03. Runnable { 02.  Login or register to post comments Geertjan Wielenga replied on Wed. ringerc. the ability to mark an action as being asynchronous).12:27am Excellent feedback.class MyAction implements ActionListener. (which is a new feature in 6.12:17am This example doesn't appear to take the need to avoid blocking the UI while performing database work into account.. Thank you.e. i. That attribute causes the action to be processed asynchronously. .8. get what is important from c 05. These asynchronous actions can simulate SwingWorker: view source print? 01.isEventThread().assert !EventQueue. } Another approach would be to use SwingWorker.model" is appropriate for the code name base: . Select the JAR you created in the previous subsection and complete the wizard.// perform the work 10.org. 2009/12/08 .org/NetBeansDeveloperFAQ#Threading How to Create a Swing CRUD Application on NetBeans Platform 6.assert EventQueue.shop.8      0 inShare Submitted by Geertjan Wielenga on Tue.08. Right-click the DBManager's Modules node in the Projects window and choose Add New Library. 11. though note that threading on the NetBeans Platform is also discussed here: http://wiki. specifying any values you like. you add your first module to your application! The new NetBeans module will wrap the JAR file you created in the previous section. These approaches will be added to the article.} 12. 13.public void run() { 14.netbeans. Let's assume the application is for dealing with customers at shop.isEventThread().// run off AWT thread 09.} 17. 15. in which case a unique identifier "org.2:08pm Ads by DZone Wrapping the Entity Class JAR in a Module In this section.SwingUtilities. 2.// finish in AWT and update the UI 16. 1.invokeLater(this). wrapping the JAR containing the entity classes and the persistence.You now have your first custom module in your new application. Do the same as you did when creating the library wrapper for the entity class JAR. which are in the "CustomerLibrary" Java library that you created earlier: . 1. as well as the database connector JAR.xml file: Creating Other Related Modules In this section. you create two new modules. but this time for the EclipseLink JARs. wrapping the EclipseLink JARs. shop. Next. you create a simple prototype user interface. Right-click the DBManager's Modules node in the Projects window and choose Add New. at db/lib/derbyclient.jar.Note: In the Library Wrapper Module wizard.ui. Specify that it should be created in the editor position and that it should open when the application starts. In the Projects window. create yet another library wrapper module. Designing the User Interface In this section. you can use Ctrl-Click to select multiple JARs. with the code name base org. Set Customer as the window's class name prefix. providing a window that uses a JTextArea to display data retrieved from the database. this time for the Java DB client JAR. . 1. Create a new module named CustomerViewer. right-click the new module and choose New | Window Component. 2. 2. which is available in your JDK distribution. 3. 6. 4.crea teEntityManager().List<Customer> resultList = query. Use the Palette (Ctrl-Shift-8) to drag and drop a JTextArea on the new window: 4. 3.jTextArea1. These will be fixed in the section that follows. .} Note: Since you have not set dependencies on the modules that provide the Customer object and the persistence JARs.getName() + " (" + c.createQuery("SELECT c FROM Customer c").getCity() + ")" + "\n").getResultList(). 2.Query query = entityManager. Add this to the end of the TopComponent constructor: view source print? 1.append(c. the statements above will be marked with red error underlines.createEntityManagerFactory("CustomerLibraryPU").EntityManager entityManager = Persistence.for (Customer c : resultList) { 5. you enable some of the modules to use code from some of the other modules. 2. which is the name set in the persistence. choose Properties.xml file. Right-click the CustomerLibrary module. Setting Dependencies In this section. you can see references to a persistence unit named "CustomerLibraryPU". 1. and use the Libraries tab to set dependencies on the two modules that the CustomerLibrary module needs. 3. Running the Prototype In this section. i. You now have set contracts between the modules in your application.Above. called Customer. as opposed to the accidental and chaotic reuse of code that tends to happen when you do not have a strict modular architecture such as that provided by the NetBeans Platform. The IDE is now able to add the required import statements. which is in the entity classes module. choose Properties. 1. Right-click the CustomerViewer module. right-click in the editor. You should see this: . Run the application.e. because the modules that provide the required classes are now available to the CustomerTopComponent. The entity classes module needs to have dependencies on the Derby Client module as well as on the EclipseLink module. and use the Libraries tab to set dependencies on the two modules that the CustomerViewer module needs. In addition.. giving you control over the dependencies between distinct pieces of code. Start your database server.there is a reference to one of the entity classes. The CustomerViewer module needs a dependency on the EclipseLink module as well as on the entity classes module. if they are different to the above. and choose "Fix Imports". Open the CustomerTopComponent in the Source view. Adapt these bits to your needs. you run the application so that you can see that you're correctly accessing your database. 2. You do this very explicitly by setting intentional contracts between related modules. for a NetBeans Platform explorer view. How to Create a Swing CRUD Application on NetBeans Platform 6. NetBeans Platform explorer views are Swing components that integrate better with the NetBeans Platform than standard Swing .You now have a simple prototype. The sections that follow describe these patterns in detail. you change the JTextArea. consisting of a NetBeans Platform application that displays data from your database. Read In this section. which you will extend in the next section. 2009/12/08 . introduced in the previous section.8      0 inShare Submitted by Geertjan Wielenga on Tue. some very specific NetBeans Platform coding patterns need to be implemented.2:08pm Ads by DZone Integrating CRUD Functionality In order to create CRUD functionality that integrates smoothly with the NetBeans Platform. you will have a generic hierarchical model provided by a NetBeans Platform Node class. which can be displayed by any of the NetBeans Platform explorer views.return em.crea teEntityManager(). This section ends with an explanation of how to synchronize your explorer view with the NetBeans Platform Properties window.createQuery("SELECT c FROM Customer c").getName() + " (" + c.createEntityManagerFactory("CustomerLibraryPU").@Override 2.//} 2.//for (Customer c : resultList) { 5. they support the notion of a context.final class CustomerTopComponent extends TopComponent implements ExplorerManager. 3. 3.Query query = entityManager.components do. Representing your data. and use the Libraries tab to set dependencies on the Nodes API and the Explorer & Property Sheet API. which enables them to be context sensitive. change the class signature to implement ExplorerManager. 1. Next.// jTextArea1.public ExplorerManager getExplorerManager() { 3. choose Properties.List<Customer> resultList = query. 6. In your TopComponent.EntityManager entityManager = Persistence.getCity() + ")" + "\n"). Right-click the CustomerViewer module.append(c. Among other things. . 2.Provider: view source print? 1. 4.getResultList().Provider You will need to override getExplorerManager() view source print? 1. delete the JTextArea in the Design view and comment out its related code in the Source view: view source print? 1. Choose the BeanTreeView and complete the wizard.nodes. You should now see BeanTreeView in the Palette.IntrospectionException. Then browse to the org-openide-explorer.Customer. .Exceptions. Create a factory class that will create a new BeanNode for each customer in your database: view source print? 01. choose Palette Manager | Add from JAR. 4. 06. Switch to the TopComponent Design view.nodes. Drag it from the Palette and drop it on the window.import org.util. especially the screencast dealing with the Nodes API and the Explorer & Property Sheet API. declare and initialize the ExplorerManager: view source print? 1.openide. 12.jar.openide.import demo.ChildFactory.private List<Customer> resultList. 5. 07.public class CustomerChildFactory extends ChildFactory<Customer> { 10.import org.import java.} At the top of the class. 03. 04.BeanNode. 11. 02.openide. within the NetBeans IDE installation directory.Node. which is in platform11/modules folder.import org.openide.private static ExplorerManager em = new ExplorerManager().util.nodes.4. 08.import org. right-click in the Palette.List. 09. 05. Note: Watch Top 10 NetBeans APIs for details on the above code.import java.beans. for (Customer customer : resultList) { 20. 32.} 6.try { 28.this. use the ExplorerManager to pass the result list from the JPA query in to the Node: view source print? . 15.return null. 23.Exceptions. 35.} 33.return new BeanNode(c).public CustomerChildFactory(List<Customer> resultList) { 14.list.return true. 17.resultList = resultList. 31.13.printStackTrace(ex). Back in the CustomerTopComponent.@Override 18.} catch (IntrospectionException ex) { 30.add(customer). 25.protected boolean createKeys(List<Customer> list) { 19.} 24.protected Node createNodeForKey(Customer c) { 27.} 22. 21.@Override 26.} 16. 29.} 34. //for (Customer c : resultList) { 6.createEntityManagerFactory("CustomerLibraryPU"). 5.List<Customer> resultList = query. 9. displayed in a BeanTreeView. 4. the BeanTreeView is not synchronized with the Properties window. which is available via Window | Properties.associateLookup(ExplorerUtils.EntityManager entityManager = Persistence. Once the application is running. Run the application again and notice that the Properties window is now synchronized with the explorer view: .getName() + " (" + c.append(c. In other words. 3.//} 7. Here we add the TopComponent's ActionMap and ExplorerManager to the Lookup of the TopComponent. 8. 7.em.1. Synchronize the Properties window with the BeanTreeView by adding the following to the constructor in the TopComponent: view source print? 1.setRootContext(new AbstractNode(Children.crea teEntityManager().createLookup(em.getCity() + ")" + "\n"). getActionMap())).getResultList(). Notice that even though the data is available. true))).createQuery("SELECT c FROM Customer c").Query query = entityManager. open the Properties window. 2.// jTextArea1. nothing is displayed in the Properties window when you move up and down the tree hierarchy.create(new CustomerChildFactory(resultList). Run the application. However. Inc. you're also able to swap in a different explorer view without needing to change the model at all because the ExplorerManager mediates between the model and the view. as you would be able to do with a JTree.          « first ‹ previous 1 2 3 4 5 next › last » Your rating: 0 Average: 3 (1 vote)    Login or register to post comments 63986 reads Printer-friendly version (Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone.Now you are able to view your data in a tree hierarchy. Finally. you are now also able to synchronize the view with the Properties window.) Comments . invokeLater(this).SwingUtilities.} Another approach would be to use SwingWorker. Thank you. which can be achieved with.// finish in AWT and update the UI 16. it also makes it a fairly useless example of using the platform in practice.} 06.} 12. 04.public void run() { 14.assert EventQueue.12:17am This example doesn't appear to take the need to avoid blocking the UI while performing database work into account.// setup inside AWT thread.} 17. 2009/12/09 .// run off AWT thread 09. (which is a new feature in 6. That attribute causes the action to be processed asynchronously.assert EventQueue. 15.8.e. as such concurrency issues are crucual when doing database work. These asynchronous actions can simulate SwingWorker: view source print? 01. 08. 2009/12/09 . literally. 11. though note that threading on the NetBeans Platform is also discussed here: http://wiki.// perform the work 10. While that keeps it simple.netbeans.assert !EventQueue. Runnable { 02. .isEventThread(). These approaches will be added to the article.public MyAction(MyContext c) { 03. 13.public void actionPerformed(AE ev) { 07.isEventThread().. ringerc. the ability to mark an action as being asynchronous).org/NetBeansDeveloperFAQ#Threading Something else that's possible is to integrate with the NetBeans progress bar. 3 lines of code.isEventThread().class MyAction implements ActionListener.Craig Ringer replied on Wed.  Login or register to post comments Geertjan Wielenga replied on Wed.12:27am Excellent feedback. One approach is to register actions in the layer file which then enables you to add an attribute to the layer entry. i. get what is important from c 05. That will be fixed. containing two JTextFields. you will add the current Customer object to the Lookup. Use the Palette (Ctrl-Shift-8) to add two JLabels and two JTextFields to the new window. you will listen to the Lookup for the introduction of Customer objects.2:08pm Ads by DZone Update In this section. 2. In other words. you will update the JTextFields in the editor. Next. set "Editor" as the class name prefix. Whenever a new Customer object is introduced into the Lookup. Right-click the CustomerEditor module and choose New | Window Component. Make sure to specify that the window should appear in the editor position and that it should open when the application starts. you will first create a new module. you will synchronize your JTextFields with the NetBeans Platform's Undo. within that new module.8      0 inShare Submitted by Geertjan Wielenga on Tue. 1. 3. you will create a new TopComponent. you want the NetBeans Platform's existing functionality to become available so that. 2009/12/08 . and Save functionality. To this end. Whenever a new Node is selected in the viewer module. you will need to use the UndoRedoManager.How to Create a Swing CRUD Application on NetBeans Platform 6.editor as its code name base. together with the SaveCookie. Then. instead of needing to create new functionality. In the editor module. when the user makes changes to a JTextField. named CustomerEditor. In the GUI Builder. Redo. for each of the columns you want to let the user edit. you'll simply be able to hook into the NetBeans Platform's support. with org. Create a new module. Set the texts of the labels to "Name" and "City" and set the variable names of the two JTextFields to jTextField1 and jTextField2. In the final panel of the wizard. The editor will be provided by a new NetBeans module. So. the window should now look something like this: .shop. You will need to let the viewer module communicate with the editor module. you first create an editor. Note: Right-click the application project and choose "Clean". Also check that the BeanTreeView in the CustomerViewer will stretch horizontally and vertically when the user resizes the application.xml file to specify that the CustomerTopComponent window will appear in the explorer mode. selecting the BeanTreeView.. it will remain in the editor mode. thus deleting the user directory) and enabling the CustomerViewer to be displayed in the position currently set in the layer. until you do a "Clean".xml file. if the CustomerViewer was initially displayed in the editor mode.xml file. Therefore. thus resetting the user directory (i. Go back to the CustomerViewer module and change its layer.e. and then clicking the arrow buttons in the toolbar of the GUI Builder. 5. Why? Because whenever you run the application and close it down. after changing the layer. the window positions are stored in the user directory. Run the application and make sure that you see the following when the application starts up: . Check this by opening the window.4. 06. 05. 04. 07.getCity()).setDisplayName(c.singleton(c)" below): view source print? 01. Now we can start adding some code. Firstly. instead of a BeanNode.singleton(c)).getName()). That enables you to add the current Customer object to the Lookup of the Node.@Override 02.// try { . Lookups.LEAF. in the CustomerChildFactory class. as follows (note the "Lookups.node.6.return node.setShortDescription(c.protected Node createNodeForKey(Customer c) { 03. we need to show the currently selected Customer object in the editor: o Start by tweaking the CustomerViewer module so that the current Customer object is added to the viewer window's Lookup whenever a new Node is selected. Do this by creating an AbstractNode.Node node = new AbstractNode(Children.node. allInstances().08.// 09.if (!coll.} } return new BeanNode(c).public void resultChanged(LookupEvent lookupEvent) { 03. whenever a new Node is created.// 11. set a dependency in the editor module on the module that provides the entity class. Now.printStackTrace(ex).// 13. First. a new Customer object is added to the Lookup of the Node. which happens when the user selects a new customer in the viewer. } catch (IntrospectionException ex) { Exceptions. 04.isEmpty()) { 06. o Next. 05.// 12.Lookup.Result r = (Lookup.public final class EditorTopComponent extends TopComponent implements LookupListener o Override the resultChanged so that the JTextFields are updated whenever a new Customer object is introduced into the Lookup: view source print? 01. change the EditorTopComponent class signature to implement LookupListener: view source print? 1. return null.Collection<Customer> coll = r.getSource(). as well as the module that provides the persistence JARs.// 10.for (Customer cust : coll) { .Result) lookupEvent.@Override 02. o Let's now change the editor module in such a way that its window will end up listening for Customer objects being added to the Lookup. setText("[no name]").} else { 11.lookupResult(Customer. 08.getName()). The global context proxies the context of the selected Node.jTextField2. That is what is then passed to the resultChanged. 12. All of the above starts happening.result = Utilities.jTextField1.jTextField1. 09. 05. i. the LookupListener becomes active.setText(cust.} 07.@Override 02.} o Now that the LookupListener is defined..Result obtained from the global context. because it is the currently selected Node. For example.actionsGlobalContext().} 10. 13.e.@Override 09.result. 08.jTextField2.setText("[no city]"). we add it to the Lookup. if "Ford Motor Co" is selected in the tree hierarchy.public void componentClosed() { . the Customer object for "Ford Motor Co" is added to the Lookup of the Node which. 06.setText(cust.07. 04. as you can see below: view source print? 01.resultChanged(new LookupEvent(result)).getCity()). causing the text fields to be populated. whenever the editor window is opened.} 14.public void componentOpened() { 03. we need to add it to something. Here.addLookupListener(this).cla ss). means that the Customer object for "Ford Motor Co" is now available in the global context. 12.result. 11. declare the result variable at the top of the class.10.} Since the editor window is opened when the application starts. like this: view source print? 1. the LookupListener is available at the time that the application starts up. o Run the application again and notice that the editor window is updated whenever you select a new Node: However. o Finally.result = null.removeLookupListener(this).private Lookup.Result result = null. notice what happens when you switch the focus to the editor window: . actionsGlobalContext().lookupResult(Customer.result = WindowManager. To this: view source print? 1. One drawback of the approach above is that now our EditorTopComponent only works if it . which is a string constant that you can find in the source code of the CustomerTopComponent. we will use the local Lookup provided by the Customer window. as pointed out above.class).cla ss).getDefault(). The string "CustomerTopComponent" is the ID of the CustomerTopComponent.Because the Node is no longer current.result = Utilities. the global context proxies the Lookup of the current Node. we cannot use the global context.getLookup(). Rewrite this line: view source print? 1. Therefore. the Customer object is no longer in the global context.lookupResult(Customer.findTopComponent("CustomerTopCo mponent"). This is the case because. in this case. Instead. let's work on the Undo/Redo functionality.private UndoRedo.Manager manager = new UndoRedo. To that end. the "Undo" button and the "Redo" button. 7. . so that developers of alternative editors can know that they need to identify the viewer TopComponent this way. or you need to rewrite the selection model. o Declare and instantiate a new UndoRedoManager at the top of the EditorTopComponent: view source print? 1. as shown below: Note: Since you are now using AbstractNode. as described in the Nodes API Tutorial. What we'd like to have happen is that whenever the user makes a change to one of the JTextFields. as described here by Tim Boudreau. as well as the related menu items in the Edit menu. the NetBeans Platform makes the UndoRedo.Manager(). become enabled. If you take one of the above approaches. you will find that the context is not lost when you switch the focus to the EditorTopComponent.Manager available. no properties are shown in the Properties window. instead of BeanNode. Either this needs to be explicitly documented. You need to provide these yourself.can find a TopComponent with the ID "CustomerTopComponent". Secondly. tweak the code above to suit your business requirements. because "all" refers to a number of different documents. override the getUndoRedo() method in the EditorTopComponent: view source print? 1. Therefore. we do not want to save "all". Thirdly.return manager.} o In the constructor of the EditorTopComponent.jTextField1. The functionality works exactly as you would expect. the "Save All" button is available in the NetBeans Platform toolbar.getDocument(). you probably do not want the undo/redo functionality to become available.getDocument(). For example. 4. which is the editor that we are reusing for all the nodes in the tree hirerarchy. In our current scenario. when Enter is pressed. we need to integrate with the NetBeans Platform's Save functionality: o By default. within the related methods that you need to implement. o Run the application and show the Undo and Redo functionality in action.addUndoableEditListener(manage r).jTextField2. add a KeyListener to the JTextFields and. we only have one "document". In our case. the buttons as well as the menu items. 2.@Override 2. Remove the "Save All" button and add the . add the UndoRedoListeners: view source print? 1.o Next.addUndoableEditListener(manage r). 8. You might want to change the KeyListener so that not ALL keys cause the undo/redo functionality to be enabled.public UndoRedo getUndoRedo() { 3. . o Set dependencies on the Dialogs API and the Nodes API..<folder name="Toolbars"> 02.<attr name="position" intvalue="444"/> 06. add a call to fire a method (which will be defined in the next step) whenever a change is detected: view source print? 01..<folder name="File"> 03.shadow"> 04. Instead of the "Save All" button. you now have the "Save" button available..<file name="org-openide-actions-SaveAction. 04..</file> 07."Save" button instead..instance"/> 05.. 03..</folder> 09. 05.shadow_hidden"/> 08. o In the EditorTopCompontn constructor.</folder> When you now run the application. . by adding the following to the layer file of the CustomerEditor module: view source print? 01.<file name="org-openide-actionsSaveAllAction..public EditorTopComponent() { 02. you will see a different icon in the toolbar.<attr name="originalFile" stringvalue="Actions/System/org-openide-actionsSaveAction. public void removeUpdate(DocumentEvent arg0) { 24.public void changedUpdate(DocumentEvent arg0) { 27.public void insertUpdate(DocumentEvent arg0) { 09.} 11.public void removeUpdate(DocumentEvent arg0) { 12.06.//Create a new instance of our SaveCookie implementation: .fire(true). 13.} 29. 28.}).fire(true). 10. 16.fire(true).} 26. 30. 31.addDocumentListener(new DocumentListener() { 20.jTextField2.public void insertUpdate(DocumentEvent arg0) { 21. 19.fire(true).jTextField1.} 23.fire(true).getDocument(). 07. 18.fire(true).} 14.addDocumentListener(new DocumentListener() { 08.}).} 17.public void changedUpdate(DocumentEvent arg0) { 15. 25.getDocument(). 22. //we add SaveCookie impl to Lookup: 05. 37.} 41. 34. 36.... we remove the SaveCookie impl from the lookup: 08.. An implementation of the SaveCookie from the Nodes API is added to the InstanceContent whenever a change is detected: view source print? 01. 40.. 04.//Add the dynamic object to the TopComponent Lookup: 38.content.content.remove(impl).content = new InstanceContent(). the method that is fired whenever a change is detected.//Create a new instance of our dynamic object: 35.add(impl). 43.} else { 07.public void fire(boolean modified) { 02. 39.} .if (modified) { 03.//Otherwise.32. 44. 09. 33.//If the text is modified.impl = new SaveCookieImpl().. 42. o Here are the two methods referred to above. 06.associateLookup(new AbstractLookup(content)).... First. //so that it will only be usable when the next change is made 26.+ jTextField1.Object result = DialogDisplayer. 12.//to the JTextArea: 27.getText() + " (" + jTextField2.public void save() throws IOException { 16.if (NotifyDescriptor. 20.notify(message).Confirmation message = new NotifyDescriptor.@Override 15.} 31.fire(false). 17.YES_OPTION.//When user clicks "Yes".} o Run the application and notice the enablement/disablement of the Save button: . 21.} 32.QUESTION_MESSAGE). 23. 22. 24.getDefault(). indicating they really want to save.getText() + ")\"?".private class SaveCookieImpl implements SaveCookie { 13. 29.} 11. 14.//Implement your save functionality here. 25.OK_CANCEL_OPTION.10.NotifyDescriptor.Confirmation("Do you want to save \"" 18.//we need to disable the Save action. 30.equals(result)) { 28.NotifyDescriptor. 19. getCustomerId()). we add some JPA code for handling persistence of our changes. nothing happens when you click OK in the dialog above.entityManager.class.getTransaction(). 4. Add the line "customer = cust. Note: The "customer" in customer. customer. we add JPA code for persisting our change.setName(jTextField1. 3.Note: Right now.EntityManager entityManager = Persistence.commit(). Do so by replacing the comment "//Implement your save functionality here.setCity(jTextField2.createEntityManager(). 6.getCustomerId() is currently undefined.begin().entityManager.getTransaction().getText()). In the next step.c. o Next. 5.createEntityManagerFactory("CustomerLibraryPU" ).find(Customer." in the resultChanged (as .getText()).Customer c = entityManager. 2.c." The comment should be replaced by all of the following: view source print? 1. setText(customer.@Override 02.for (Customer customer : c) { 07. view source print? 01.customer = cust. 10.} o Run the application and change some data. 05.if (!c. 14. we have no "Refresh" functionality (that will be added in the next step) so.jTextField2.Result r = (Lookup.jTextField1. 04.public void resultChanged(LookupEvent lookupEvent) { 03. 09.getName()).jTextField1.Lookup. restart the application.getSource().} 15.setText("[no city]").setText("[no name]").allInstances().isEmpty()) { 06. after declaring Customer customer.Collection<Customer> c = r.} else { 12.jTextField2.} 11. Currently.getCity()).Result) lookupEvent. for example. the tree hierarchy shows the persisted customer name for "Toyota Motor Co": . 08.shown below). at the top of the class. to see the changed data.setText(customer. which is then used in the persistence code above to obtain the ID of the current Customer object. Here. 13. so that the current Customer object sets the customer. we will add a "Refresh" menu item to the Root node so that the user will be able to manually refresh the viewer. 05. create a new Node. 03.public class CustomerRootNode extends AbstractNode { 02. in this example. However. 06. o In the main package of the CustomerViewer module.9. Fourthly.} . which will replace the AbstractNode that we are currently using as the root of the children in the viewer. You might want to add a Timer which periodically refreshes the viewer.public CustomerRootNode(Children kids) { 04. view source print? 01. we need to add functionality for refreshing the Customer viewer. Note that we also bind a "Refresh" action to our new root node.setDisplayName("Root").super(kids). 21. for refreshing the view: view source print? 1.Action[] result = new Action[]{ 11.} 25. 17. 13.public Action[] getActions(boolean context) { 10. 26.private final class RefreshAction extends AbstractAction { 16.CustomerTopComponent.createEntityManagerFactory("CustomerLibraryPU" ).NAME.07.@Override 09. 12.refreshNode().public void actionPerformed(ActionEvent e) { 22.} 20. 23.return result. .} 14.} 24.new RefreshAction()}.public RefreshAction() { 18. "Refresh"). 15. 19.public static void refreshNode() { 2.} o Add this method to the CustomerTopComponent.createEntityManager(). 08.EntityManager entityManager = Persistence.putValue(Action. we are now using our CustomerRootNode instead of the AbstractNode. o In your save functionality.List<Customer> resultList = query. o Run the application again and notice that you have a new root node.} Now replace the code above in the constructor of the CustomerTopComponent with a call to the above. true))). 4. . You can take different approaches when implementing this extension to the save functionality.Query query = entityManager. whenever data is saved. you might want to create a new module that contains the refresh action.create(new CustomerChildFactory(resultList). 6.3. As you can see. add the call to the method above so that.em. For example. That module would then be shared between the viewer module and the editor module.getResultList().setRootContext(new CustomerRootNode(Children. which calls the code above. The CustomerRootNode includes the "Refresh" action. an automatic refresh takes place. and notice that the viewer is updated. with a "Refresh" action: o Make a change to some data. save it.createQuery("SELECT c FROM Customer c"). providing functionality that is common to both. 5. invoke the Refresh action. 8      0 inShare Submitted by Geertjan Wielenga on Tue. 02. 1. the NetBeans Platform Undo and Redo buttons are enabled or disabled. In the next step of the wizard. you allow the user to create a new entry in the database.awt.ActionEvent. 2009/12/08 . The new action should be displayed anywhere in the toolbar and/or anywhere in the menu bar.import java. In the New action. the Save button is enabled and disabled correctly. together with emptied JTextFields: view source print? 01. let the TopComponent be opened. 2.awt. letting the user save changed data back to the database.You have now learned how to let the NetBeans Platform handle changes to the JTextFields. Right-click the CustomerEditor module and choose "New Action". Note: Make sure that you have a 16x16 icon available.public void actionPerformed(ActionEvent e) { . call the action NewAction. How to Create a Swing CRUD Application on NetBeans Platform 6. 04. 03.ActionListener. which the wizard forces you to select if you indicate that you want the action to be invoked from the toolbar. Whenever the text changes.event. 06.import java.2:08pm Ads by DZone Create In this section. Use the New Action wizard to create a new "Always Enabled" action. Also.public final class NewAction implements ActionListener { 05.event. tc. 4.public void resetFields() { 2. add the following method for resetting the JTextFields and creating a new Customer object: view source print? 1.customer = new Customer(). 08.Confirmation("Do you want to save \"" 04.open().tc. 13.} Note: The action implements the ActionListener class. 09. since you'll simply be able to use the same Action classes that you used in your original application.jTextField2.EditorTopComponent tc = EditorTopComponent.tc.+ jTextField1. 5.OK_CANCEL_OPTION.} 12.getDefault().setText("").} 3. ensure that a return of null indicates that a new entry is saved. instead of an existing entry being updated: view source print? 01. 10. In the SaveCookie.jTextField1.07. without needing to rewrite them to conform to Action classes provided by the NetBeans Platform! In the EditorTopComponent.public void save() throws IOException { 02.Confirmation message = new NotifyDescriptor. 11. Imagine how easy it will be when you port your existing Swing application to the NetBeans Platform.requestActive().NotifyDescriptor.getText() + " (" + jTextField2. put there by the New Action wizard. 06.getText() + ")\"?". which is bound to the application via entries in the layer file. .setText(""). 05.resetFields().NotifyDescriptor. 03. 3.QUESTION_MESSAGE). 31.Customer c = entityManager.customer.fire(false). 08.setName(jTextField1.setCity(jTextField2.setCustomerId(resultList.entityManager.} else { 24.equals(result)) { 15.EntityManager entityManager = Persistence.persist(customer).//When user clicks "Yes".if (customer. 23.class. 21.entityManager.if (NotifyDescriptor.commit().setCity(jTextField2.entityManager.getDefault(). 09.List<Customer> resultList = query. 29.crea teEntityManager().setName(jTextField1. 16.//we need to disable the Save button and Save menu item. 25. indicating they really want to save. 17.YES_OPTION.c.commit(). 10.notify(msg).getTransaction().c. 27.getCustomerId() != null) { 19.getCustomerId()).//to the text field: 14.customer.Object result = DialogDisplayer.createEntityManagerFactory("CustomerLibraryPU").//so that it will only be usable when the next change is made 13.getText()).entityManager. 22.//add more fields that will populate all the other columns in the table! 30.getText()).getResultList().customer. cude.Query query = entityManager.size()+1).getText()). 20.getTransaction(). 11.find(Customer.getText()). 12.getTransaction(). 26.createQuery("SELECT c FROM Customer c"). 28.07. 18. .begin(). 2. Depending on where you want to bind it. Get the current Customer object. For help on this point. You have learned how to create a new NetBeans Platform application with CRUD functionality for a given database. 35. See Also This concludes the article. return an 'Are you sure?' dialog. and then delete the entry. Using the concepts and code outlined above. Delete In this section. implement the Delete action yourself. DeleteAction.} 33. You have also seen many of the NetBeans APIs in action.} 4.32. Instead of saving. read the article again. see the following resources: . Read the article again for help. focusing on the part where the "Save" functionality is implemented. keyboard shortcut. you now want to delete an entry from the database. For more information about creating and developing applications on the NetBeans Platform. or combinations of these. you will need to use a different approach in your code. let the user delete a selected entry in the database. Decide whether you want to bind it to a Customer node or whether you'd rather bind it to the toolbar. 1. the menu bar. Run the application again and add a new customer to the database. while comparing it to the "Refresh" action on the root node. especially by looking at how the "New" action was created. Create a new action.} 34. . 708:989   .147 :894207. .  .5503/ .20 3   .%0970. 09. . /07 4:300/944..070954707. 099       #9 .3.077/0  5:-.07 !74./07 .8883.3090.88 :894207%45425430390903/8%454254303925020398 54707.3/9054707 !745079 $009!     09 .0843904/08!.3.084:7...3..0 5739  13. 54707.07  .07  709:73 02  .3.07 !74.3/:8090 -7.90:894207'00724/:0 .<    .4480!74507908 .0 5739   .7089.9:7094250203954707.077/00954707..-94809/0503/03.084:7.3. .9.0.4/0 0850.7  .3.-4.3/9054707 !745079$009 !    $9.9.0 5739  57.07 ..7003.9490%4542543039083. 54707.88 /0.07//1742# %03-7480949047 4503/0 054707 .38!8147/09.89/0.3/39. 908.070230 54707..0990.9089.3.3..%45 090.09054707.07  490. < 9909454190.390!.84390.835..4480 !.3.39904/08!..084:7.91472.0990 .70.0 79 . 300.947:894207    57..947 4480900.9.947.90.90..1...3%700'0390!.3%700'0.9174290!.05943  25479.24/:0814/07 9390090.0990 7.34/01470.943.9470903/8 /.0990..80 .38 3974850..-.70.943 /70... :9 89  2547947 4503/0 34/08 0...38389.:89420734:7 /.084:7..42509090.7/ 4:84:/34 8000....9. -0..3//74594390 3/4     70.059438     5:-.889.3/.0 5739  25479/024 :894207   25479.947  2547947 4503/0 34/08 4/0  2547947 4503/0 :9 .34/0  2547947 4503/0 34/08 /.90 89:894207708:989   .88 :894207/. 07945.0 0   709:733:  <  <    <   .70.059430   .059438 5739$9.   97   709:7330 0.90/ -440. 5:-.90/ 4/0.70.3.9008 89:89420789   147 :894207.390:894207%4542543039 :809054707.3.943.34/0 ..904/0470 :894207.   <.947 89:894207708:989   98 708:989708:989  <     .:894207/...// .077/0  57490..8890 708:989174290!6:07394904/0 .9.084:7.%7.0 5739 .:894207708:989   89 ..077/0  57490. 3974850.:894207   <  709:7397:0  <     . 70. 90399.947 :894207-7.90":07 $%.70..70.3.7!& .0 .70.3.07   ":076:070399.#  :894207.07 !0788903.3. 399.90399.94/0 /703 ..3.070399.947 708:989 97:0   .3.07 ..90 30 :894207/.   89:894207708:9896:07 09#08:989   02 809#44943909 30 -897.07. . 708:989   .147 :894207. . %0970. 09.5503/ . .20 3   . . 943.084:7.-0 /85.884.-0.743090!745079083/49900.90..//390 14439490.43897:.94387:333 450390!74507908 3/4 49.8..090..9044:5 02  09.5  0700..0/390!745079083/4034:24.3//43909700 07..3.943.0 .55. 099      #:390.943..5.8.09.<    .3/349.70.3%700'0-.7.3%700'0 900.947390%4542543039 .//90%4542543039 8.9..0/3.     $3.990!745079083/4834 83.079490 44:54190%4542543039    #:390.7430/990054707..55.. 0..55..3/4!74507908 3490747/8 34938 /85.3%700'0834983.7430/990!74507908 3/4 .943  3.0 5739  ..0:5.3/54707.3.0394:90/.09.9044:5 54707&98 . :9478.7034.9.-0948.84.79.0.  4220398 .0990!74507908 3/4  O O O O O O O O O 1789 570.0 .93  . 44:.84.7.3/90..9./1107039054707.490  O O O 4347708907945489.4220398 70./8 !73907 1703/.3.309024/0.70.908-090039024/0 .3.4:8      309  .3/9870508.970007.-094/49 .07 4: 70.04:7/.9.53. .70904534384190770850..07.743090.%700 40.-09483.89  4:77.0 3.094:9300/3 94.:809054707.84:4:/-0.-094.-0.3/349948041430  3.0. 4:.07843 490 534380570880/398.0720/.  7.#3077050/430/  . . 9.7949.43.9.090300/94.03 /43/.4:39 09.9..91472357..4/-4.390&050714723 /.2 %80.9005898250 9.550.88:08.88:...8047394.-.4220398  0079.0 .8047  O 4347708907945489.089.1.7050/430/  .7:80088 0.  .:7703.842.-.250/4083 9.3003.:..70.25041:83905.7:. . -9942.9.0 5739  .7.9438390.9:70 3   0 90.070397  %. 7307. %.94325020398 .382:.83.   .943890307 #:33.0039100/-.7434:8  .039":0:0 8..9-010/ %.7434:8 .5574.0880/../   ..90303.90$34707 .34:  30.084:7.//.997-:90.3010.94394-0574.-084:94.943.88 .:80890...83.  .997-:909490.3.894708907 .8-03..943 43909.88079..83.-0  5:-.2 .039%70.7434:8 %080..0710.8..9438.3.. . / 09.9825479..943!0714720/ 0.4/ .88079.039":0:0 8.   .391742.809:538/0%970.039%70.  <  5:-./    .. . 7:3411%970./  . . 039%70.907 98   <    5:-.039":0:0 8.88079.4/ 7:3   ../   .40.50714729047  $3&9908 3. . 1383%.0 94:34909.5574.79.:880/070 995.5574.4:/-094:80$34707 %080.//0/9490 .08-0.914728..9970.38!.9090&  <  <  34907.84/8.3/:5/../34390090. .  309-0.38 47. /3 $420930809.4/0  ..3 -0..90990090.9 85488-08943907.04507"%70.0.7 . 30841..380.0/9 907.385747088-.090. 90..70 $:-2990/-0079.$3#& 55.91472            3$.43%:0  .3003.94343090.38!.49470. . 90.   52 /8-430 &5/.//90 .420.3/$..30/947 %00/947-0574.70.448003/442543039  .898.550..9 4: 825-0.0/3949044:5 4::5/.3/80990.90.80     #9 .798 39013.00724/:0 4:.08.38 24/:0 $4 4:1789.38!..30894.91472 88:55479 %49803/ 4:300/94:8090&3/4#0/4.90/390.93024/:0 4: .422:3.-0849.9949044:5 3900/94724/:0 4:89039490 44:5147903974/:.3024/:0 %03 939.7.98 3974/:.9984:/45030390.943.-0894.70.39940990:8070/9 4:300/940990.943.94389.9  3890.30:8942074-0.3394%090/8 1470.0990 97 $19  94...3/ 9.90301:3.73900/947548943.55.00724/:0.38!.994-0.4:2384: .70.08:7094850.98 030.3/%090/  390&:/07 903/484:/3444842093098 .3.943.07.9903/484:/.90.304/08800.:77039:8942074-0.94341:8942074-0./41300/394.20.20/:894207/947 947 845 0/947.4/0 3.3990090.30%4542543039 ..304190.%090/  4:.890.943 4:1789.91472 8&3/4 #0/4  .07  940907990$.3024/:0 3.90 39880..3/./0/-..0440    70.90990 0/94724/:0 030.38!.19.20-.7/  809/947.439..3/94%090/8949030 3/4 $099090984190.9090%090/83900/947  09 4:83.-08.//94.4190.90.01:3.90:894207/94724/:0.883.5.70.30090.74304:7%090/8990090.3/9.208419094%090/894%090/.9 3490747/8 0390:8072...-0944439490 090.07.-0 3.205701     &8090!..91472 808931:3. 74190&:/07    #:390./85.07 21094850.3/.7089470/390:807/70..44800.0/3 90548943.55.55.947 %0701470 190 :894207'007...3/903.3/.3 .798:5 .0390:8077080890.9900.07 210 0.98- 45033903/4 800.943.390.3 9:8708099390:807/70.9.3098.3%700'0390:894207'00789709.3/03.07 210  84.947 .4809 /43 903/45489438..9490:894207'00724/:0...94:8009014430390 .1 9.3/.:80030.93900.3390 0/94724/0 :394:/4.774 -:99438390944-.:77039809390.90.1907.3390 .943 0.0..55.94389.739005470724/0  490#9 ..0/3900/94724/0 9702.3%700'0 .55.08:709.990:894207%45425430393/4.3/2.074:7:390..079.947  0 9:8 /009390:807/70.9.-390:894207'00794-0/85.0...9435740.   4-.3/. 47439..943.839..55.550. 3-897. -04  .9949044:541904/0 .79.34/0 390:894207/.:77039:8942074-0..79-90..94/0 /703   44:58 830943 .93.-084:94.   4/034/030 -897..390:894207'00724/:0849.0 5739   ..904/0470 :894207.:77039 :8942074-0. 099  709:7334/0  .   40.20    34/0 809$47908..// 90. 09..70.81448 3490 9044:58 830943 .//0/9490.93900/947  4 $9.90/ 4/0. 304/08800.947.:77039 800.90/:8942074-0.07.   34/0 80985.077/0  57490.084:7.75943 .88 %.20 .903./41.70.98.389.94/0 3890. 0.//38420.4/0 789 0300/948490.0073/4 844:5030.990.90/ 498-. . 97 .  . . 709:73300.34/0 .   . . 059430   . 3974850.9..<.943. . 0 0   ..%7..059438 5739$9.. . 709:733:  . . 9574./089050788903.0#8   4 09 ..30/ 44:5.0 5739  5:-.:894207390.077/0  5:-..4/ 708:9.0   40.0/3949044:5 .30:8942074-0..9574.88 .0 5739   .03944:5..3900/94724/:0439024/:09.30.08  1 .//0/949044:5 789  809.077/090708:9.98-03.98./0890 0399.:89.//0/94 9044:541904/0  4 09 834.4 8259    147 :894207..983974/:. .943:894207./0503/03.89024/:09.4  .30900/94724/:038:.07..389..9:70942502039 44:5890307 .084:7.304/08.9983/4 03/:589033147:8942074-0.039   44:5 #08:97 44:5 #08:9  44:5.3.88/947%45425430390903/8%4542543039 25020398 44:5890307 4 .80.98.8883. 13.90/ .47 .70:5/..07 .<  < 4 030.990%090/8.90/030.039 09$4:7.9.550380390:807 800.084:7.30/849..3090/947%4542543039.30:8942074-0.70.007 . 077/0  5:-.84:...990 :8942074-0.90/4/0 47 0.//9949044:5 #08:94-9.55033  0 9044:5890307-0.089.439095740890.798.989035.:809890.20(   %090/ 809%09 34.4/ ...:8390 90910/894-0545:.250 147/494748800.9(   <  < 4   49. .914747/49474834.077/0  5:-.94384-.3800-04 ..20  %090/ 809%09 ..//0/949044:54190 4/0.7.4208 .:77039800.  %090/ 809%09 .43909  %04-..//44:5890307 98   708:9.:89 099  <  <080  %090/ 809%09 343.4/ .:89 09.9.98..90/390970007..-4.914747/494748..07900/9473/4845030/ ..//994842093  070 0..084:7.90/  4190.439094190800.389.-03904-.43909 %.30/ 30 44:5.42543039480/   .30/1742904-.  708:9 . 90 :8942074-0..42543039 5030/  708:9 &9908 .0 030.43909 88   44:5#08:9 :894207 .30/ .0 5739   .039 708:9  <     . -0.99044:58903078/0130/ 0300/94.90/4/0 20.880/9490708:9. 55038034:89..55...990..044:5890307 98   708:93:  < $3.-0.94389.:894900/947 3/4 ..55.3.9.0900/9473/4845030/0390.943.09.084:7.. /0. 708:9 7024.304/0  40.798 90 44:58903078.9909454190..-0..9909209.7090708:9.88 098 .3/349..07 349.9900/9473/48:5/.90/ 030.9.7.0 5739  57.55..074:800.0.9014.798:5  4 3..9044:5 #08:9708:93:  4 #:390.94389. 07 0901...8973.0 5739  708:9 3/4..43909 88  44:5#08:9 :894207 .3349:80904-.313/3 9084:7..089..:77039 90:8942074-0.80 0..9344:7/947%45425430394347819 .-4.0.0 90 4-.:80 . 0.399.8.88  %08973:894207%45425430398904190 :894207%4542543039 .43909 3890.3.94:..80-0..-4.084:7.98344307 3904-... %498 .5574.94384-.4/04190:894207%4542543039  30/7.:9 13/%4542543039 :894207%454 2543039 0944:5 44:5#08:9 :894207 ..4389./0/-90:8942073/4  #07909830 ..43909 %8890../ 0:80904.:770394/0 %0701470 398 ..43909574089044:54190..:80904/08344307.4190 .854390/4:9.084:7.. 44:5574.0 5739  708:9 &9908 .-. 8 843-04  490$3.313/.:  14:9.9014.43/ 09 8474390&3/4..94324/0 .990300/94/039190.7-0/070-%24:/70.9/0.7-0/3904/08!%:947./0 90804:7801 .3349.9.990.8/08.9/4.439098 349489034:89.:20390/ 849.9073.0.-4..04507841 .94/0 3890.5574./410.007 %454254303998..70843390!745079083/4 4:300/94574..00/9478.:89490/947%4542543039 .08 4:13/9.04304190.34/0 34 574507908.7034:83-897. 474:300/947079090800.    $0.%4542543039990:894207%4542543039  90798300/894-005.8 /08..04:. 08.3.90 /094.0790:8072.#0/41:3.70..3...914722.90/203:9028390 /9203: -0..943..07.80.3.42003.9030.0730 &3/4#0/4 .0890 &3/4#0/4 .38!.07.-0/ %49.9909454190 /947%4542543039 .3/90#0/4-:9943 .084:7...9 .30944304190%090/8 90 &3/4-:9943.550389.39.90&3/4#0/4 .89070..0 5739  57.07  .3/389.30&3/4#0/4.90.903/ 90090.-0   4 0.0 .3.072.3. -0/9890307 2.//&3/4.943..0 5739  %090/ 094.077/09009&3/4#0/4 2094/390/947%4542543039 .:8090:3/4.3/ 939070.//90&3/4#0/48903078 .94780.08903079490 %090/8.:2039 7  .890203:9028 %01:3.0 .3994.3/8490&3/4.94:300/942502039  .943..//&3/4.3/#0/41:3.//.:2039 7   %090/ 094.3.-0/9890307 2.9349 08.4 09 4.3.0 5739   .80.8 4:4:/050..93.9.084:7.943  90-:99438.30900890307849.07  <   4 390.90/2094/89..3.077/0  5:-.9474190/947%4542543039 .084:7..55.43897:.9 4:29. &3/4#0/409&3/4#0/4  709:73 2.0  4 #:390.943. -/4349.3990:3/4.943.994-003.-0/ 470.250  0339078570880/ 4:574-.70/41:3. .91472 8$.994-0.3/..3:2-0741/1107039/4.-0 %0701470 90.70107894..90990090.80 043 .0..9  4 /01.094 8:94:7-:83088706:7020398     %7/ 0300/943907.. -0..0-:9943.:9 90$..943...0-:99438.7.0430/4.91472 944-.01:3.420.:20398 34:7.:80 .7070:83147.74 0/4349..8900/9479.-0390090.:770398.90.7 34:7.:2039 .03.90 34/083909700707..70/4 1:3. #024.//90 .4/0.90.38!.943.-4.090$..39948.38!.. /4  .0 8973.20%44-./ -.9438 $..$.:0...943 8.9973.9438.0-:99433890.2047 4503/0 ..78  14/073.0 5739  14/073.0.200  103.//39014439490.084:7.20473.07104190 :894207/94724/:0 . $8902. 9438 $..0.0.943 389.3..47 4503/0 . :0..9973.20548943 39.  .   . ./4*//03.943 8.2047 4503/0 .0.9438 $.10  103..   . 14/07  . ../4190$...943 4:800.94170.07.3/904/08!   4 390/947%454254393.90/ .-0/0130/3903098905 030.308/090.7 3890.14/07 034:347:390..2094/ .43897:./1107039./947%4542543039           ..084390.0 5739  5:-.947 .55.090$.0 -:9943....084:7..//..43390 944-.48!.-0  4 $09/0503/03.0-:9943 4:34. 90 4.:2039.//4.0&5/.7   170 97:0   <  5:-.90 4.90 4.//4.4/ .:2039.039.7   170 97:0   <  <     %090/ 094.:2039 4...30/&5/.:2039890307 30  5:-.90 4.7   170 97:0   <  <     .4/ .4/ 38079&5/.4/ 38079&5/.7   170 97:0   <  5:-..:2039890307  .7   170 97:0   <  5:-.039..30/&5/.039.039..    %090/ 094..:2039890307 30  5:-.4/ 7024..:2039.90 4.:2039..0&5/.:2039.7   170 97:0   <  5:-.039.:2039.039.4/ 7024.90 4.:2039 4.:2039890307  . . 90.0414:7$.3..30389.0440 2502039.943 .70. .044025     . 2530 $. . 9  .30389.70.3.3.2.90.4-0.0414:7/3.43903930 389.0439039    . . 90/ .9434190 $.-4.99490%454254303944:5  .0 789 902094/9.//0/9490389.//90/3..0439039 030.98 170/030.7090942094/87010770/94..4/ 170 -440..04401742904/08!8..3.0 5739  5:-..308/090.3 24/10/   1 24/10/    ..07.2.90/ 32502039.4-0..884.944:5 .07..9044:5 30 -897.308/090.084:7.439039    <         4   070. . 190909824/10/   . . .439039 .0440259444:5  .0.// 25   <080  .//$. . 90780 07024.439039 7024..0 25   < .090$.044025174290 44:5  . 4/ 8.0440      .9708:9 .077/0  5:-.0    43172..943 44:.0  %090/ 09%09       %090/ 09%09   9748 .9432088.39948..88 $..04402525020398$...75947 "&$% *$$     -0.75947 ** !%    49108.:9 3491 2088.07 0901. <    57.05943  49108.485.75947 43172..0   ..030 49108.90 . . 0   .808 3/...939070...03:807.39 948. . -090$.0300/94/8.943   ...0. . .-00390309.30 82.849./0  .9943-0:8. . 75947 $* !%  06:.9490%0970.8 708:9  170 1.  1 49108.80   . . 09003..01:3.25020394:78..943.3/349.9070   <  <  < 4  #:390.55.-02039.943. 0 -:9943 ../8.-020394190$. 3/350788903.4 .0 414:7.422039.308  4 09 0.//8420!.490#934 3493.//!..-4. 390/...0 3903098905 0.55038034:.4/0147.30 484-705.390 .4/014750788934:7.. . :894207 09:894207/   . 809.70..3.943..3.:77039 :3/0130/ //9030.70.943 -03   :894207.8 .3.3.07 09%7..4229  490%0.90399.07   0399.:894207..07 !0788903. 8099 %090/ 09%09  0399.947 :894207-7.07 13/ :894207 .070399.07 09%7.0 5739  399.7!& ..943   .90399.:89390708:9.422039 84:/-0705.0/-.0399.084:7.:894207 09:894207/ 8.0 .25020394:78.41901443 .38.88  .3.20 %090/ 09%09  .01:3.3.9070 %0.07.3.30/ .38..:8942073. 1907/0.30/ 44:5.//0/3903098905 84 9480090 .848905078890/.30//.   .9-0.7 .077/0  5:-.. :77039 0.:77039:8942074-0.:894207 099  <  <080  %090/ 809%09 343.. 7089.9  .:894207 .:894207. 8259     147 :894207.943 070 1470.9..9(   <  < 4   #:390.943.9909454190.0   40.55.55.7.308420/.7990.:77039:894207 4-0.034 #017081:3..4/0.49474 ..9809890..3.0944-9.20(   %090/ 809%09 34..943.:894207.039 09$4:7.:894207 09.0.9.990.0 5739   .-4.9 9.389.03944:5.250 909700 07.3904190.88  849..943:894207.:894207.8903:80/ 39050788903.:89  %090/ 809%09 .3/.08  1 .039   44:5 #08:97 44:5 #08:9  44:5.73:894207.:8942073.4/ 708:9.843-04 .20147%449.084:7.20  %090/ 809%09 . #01708203:9029490#44934/0849.943.90..70170890.#01708 .94/09.3994.35..084:7..70..94/0    5:-.90.090-897.3:..04190:894207'00724/:0 ..705.304/0  .70.//.9147701708390:894207.07 3 980.88 :894207#4494/00903/8 -897.20 #449   < .943944:730744934/0  .007 40.007   4 3902.0 5739  5:-.5074/.%207.7017080890..:894207#4494/0 /703/8   8:507 /8   80985.990 :807-0..//1:3.250 0.-0942.84-3/...90.007 4909.:77039:83.  4:79 0300/94./703390.//.890 74494190.007 4: 29. 084:7.3..#01708.943  <  5:9'..0 .88#01708.943  #01708   <    5:-.70...07  . ....3.943  709:73708:9  <    57.90 13.943.3 . .90399.0 .077/0  5:-.7!& .9.943(09.9430903/8-897.4/ .943!0714720/ .90399.070399.0390   :894207%4542543039 7017084/0  <  <    < 4  //982094/9490:894207%4542543039 147701708390 .43909   .0 5739  5:-.9438 -440.3.943(  30 #01708.07.3.943(708:930 .943     5:-. 89.:0 .9.947 :894207-7.4/7017084/0   399.     .07 !0788903.70. 947 708:989 97:0  <   4705.0078:5/.943 ...90 30 :894207/.924/:04:/903-08.9  030.09.4090#01708. 8.250 4:29./4190-897.3/349.:942.-4.9.0.0/ ..090...3/900/94724/:0 574.-4.0849..943.9.3.00724/:0.70/-09003 90.94/0 %0 :894207#4494/03.01:3.09 3.3.07 .09.0 4:.3.3024/:09.943.43897:..4/0.-4.9 .4/0 .7017089.9 470...3890701708.4224394-49   4 #:390.90..88..943  4 .90/  ..30744934/0 9 .70.9474190 :894207%45425430399.9..90":07 $%.98 .   89:894207708:9896:07 09#08:989  02 809#44943909 30 :894207#4494/0 /703 .94902094/.5574.70 34:834:7:894207#4494/03890.-4..30948420/.0390.70.085.:/0890#01708..3994...990.9490..99.0  4 34:78.39...9 .08032502039398090384394908.94:.439..0 /1107039.#  :894207. ":076:070399.70.07/.890.#01708...//90.943.943 .3/ 349.943..0 84:./31:3.3800 0.0 1:3.943 %.0..55. .38!.80  49470.9 0993 90:8078.90.-.91472&3/4.3//8.91472.91472            3$.-0/.38!.3/#0/4-:99438 .9...-.7003.43%:0  .-0/47/8.3003.0790909.4770..4:.3/0.$3#& 55.70 $:-2990/-0079.3089490 %090/8 030.-0/.-0/ 84 90$.94343090.9.0340.0.30//..308 90090.0-:9943803..38!.730/4940990090.9490/... . 90.943 %030..90.90:894207/94724/:0.3/.7.94384:/ -0/85.943 4:..30.70.943 &80900 .   52 /8-430 70.-.9.44800.3070390944-.-0/.90 39880.80    #9 .490:80794.300397390/..943.0/.3/.7/94.83.70. 084:7..88 0.90.943890307    5:-...08 4:94800.943. .47.039  25479.-0 .7/ .9 0.90.43.3070390203:-.914:3/.3990..94394-03..9 0.7 390 30989054190.0 5739  25479...0.039 .0390  .943!0714720/ . ....943 0990%4542543039-045030/ 940907902590/ %090/8 . .909..13...943890307     5:-.94:.94325020398 .7/147.08:709..039 .4/ .943  490..943.94:.7    3900.40/174290 944-...9430. 9.4/ 8. 706:089.084:7.308930397-03:5/.:9  9.91472 83...943.04: 825-0.943.8-4:3/9490 ...0 5739  5:-.20.89-0034:54794:70893$3.943 94:9300/39470790 90294.4/ 708090/8   .3003978 8.943 .75947 ** !%    49108..0  <    < 490%0.7/  2.943 4 4:...94394 90090.88089.943890307.75947 "&$% *$$  .030 49108.9.91472 390/947%4542543039 ../0/-90090.0710 5:99070-900.88 .0  %090/ 09%09       %090/ 09%09   9748 .94::80/34:7473.9432502039890./41.55.943.9 .0440 038:709..9. .43147294.70.0/ 3890.-094:80908.039708390..:89420730 :894207   %090/ 809%09    %090/ 809%09    <   390$.//9014432094/147708099390 %090/8. 708090/8  9..05943  49108.38!.9432088..0    43172.30:8942074-0. 4503      9...3/.55.084:7.55.8808574.93.9089.39948.38!../947%4542543039 0901.3040.0 5739  5:-.  /947%45425430399.90/ .709:73413:3/.75947 43172. 07 0901.    -0.9708:9.485.:9    . . .3994 8..0   .808 3/.939070.03:807... . .0203:902 3491 28    .0300/94/8.0-:9943.-090$.3/$.. . 849.9943-0:8.3082.-00390309../0  . . 0399.3.70.3.4229   .88  .949090910/  1 49108.3.75947 $* !%  06:..07 .7!& .38. 8099 %090/ 09%09  0399.:894207 809.3.947 :894207-7.20 %090/ 09%09  ..07 09%7.3.943  1 ..20 %090/ 09%09  .07 13/ :894207 .:894207 809:894207/ 708:989 80  .:/0 09:894207/   .#  :894207.:894207 8099 %090/ 09%09        .070399.943  <080  ":076:070399.90":07 $%.90399. 809.8 708:9  170 1.   89:894207708:9896:07 09#08:989  .70.80   399.07 !0788903.70..07   0399.0 .:894207 09:894207/ -03   3:   :894207.38.3.07 09%7.07.3.3. 90399. . 904907.4:2383 909.38.07 09%7.-0  0399..07 507889 .943 .:894207   0399.9545:.3.90.//247010/89.4229  .3.. 9./90.3/903/0090 900397 470543985439 70.-..9.34:7.341 90090.7399490#01708.55.08   .-..7/8479.70.55.5574.907-3/99490944-...90.79.30.3/.3//0.4/0 #0.94900.4 .0.30397174290/..79.0.0 .3/..93.39 94/0090.55..90.943 0.0598 .943 47247031472.800. :89420734/04709074: /7.0 4:.9 709:73.7 90203:-.3..43.3994-3/994.-.314705 0850.730/494.70./1107039...43.90/0397390/.9825020390/ 3890.9434:7801    70.3994 -3/9 4:300/94:80.-.8480032.-443.38!83.-4.38!.3 4:34..9147.:9 47.9.9438419080 0503/3430704:.0453 ..80  $0084 %8.:/0890.91472 8009014437084:7.4/04:930/.943..-4:9.:8942079490/.38!.80 4:.3 14.7  0-4.80   0090 39880.425.943. <  <    <   #:390.943.80 &8390.9439#&1:3.79 07090$..:77039:8942074-0.03/.8.01:3./90./009074:.79.90/ 0 ./418.42-3.//.30090.943 0990:807/0090.943 0090..0 2502039900090.30.:8343905.00.94384390090..943.70.91472 .3 704:8:70 /.9434390744934/0     0990.9...943.
Copyright © 2024 DOKUMEN.SITE Inc.