I'd have to agree, I had to ask a lot of silly questions before getting some very basic things done w/ models.
On 6/7/06, Matej Knopp <[EMAIL PROTECTED]> wrote: > Hmm.. Seems like I should resurrect my unfinished "Models for dummies" > tutorial. Perhaps lack of "just-do-it-like-this" documentation causes > most of new user being confused about models and about where and how > should the components get their data from... > > I don't say the model documentation in wiki is bad. Not at all. But I > think it's way too detailed for the beginners to grasp. I hope to find > some time and write a small and concise doc, maybe that would help. > > -Matej > > Igor Vaynberg wrote: > > ditto what mataj said. a detachable model for the snippets list is a > > must. that way the list stays up to date all on its own. > > > > -Igor > > > > > > On 6/7/06, *Matej Knopp * <[EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>> > > wrote: > > > > > Hello all, > > Hi > > > > > > > > > > > > I'm just starting with Wicket and after completing my first working > > > Wicket WebPage & Panel, I'd love to get some feedback on how I'm > > going > > > about doing things. This is just a tech demo for me to prove > > > feasibility but I'm also using it to iron out some best practices. > > > > > > The app in question is just one WebPage that allows a user to save > > > "snippets" of HTML to a database. The page has a top area with a > > > ListChoice that lists all of the snippets already saved as well as > > > controls for managing them. The bottom area is a separate Panel > > that is > > > used to edit/create specific HtmlSnippet instances. As a side > > note, I > > > use the JPOX implementation of JDO for all my > > database/persistence code. > > > > > > I know it's a lot of code, but I would *greatly* appreciate it if > > > someone here could skim through it and point out anything I'm > > doing that > > > will bite me in the ass later on down the road. In particular, I > > wonder > > > about: > > > > > > 1. Do people generally just use anonymous inner classes for Button > > > event handling or write fully-subclassed private inner > > classes? > > Yes, anonymous classes are heavily used in wicket. It's uncommon to > > write fully-subclassed inner class just to implement event handling for > > button/link. > > > > > 2. To track the current state of things, I use a non-final > > > HtmlSnippet member variable and a separate model class for the > > > entered values. Does this dual-set up make sense? > > Not really. Better way is to have a model (e.g. property model) bound to > > a property of your page and having component using this model. > > > > class MyPage extends Page { > > public HmlSnippet currentSnippet; > > > > public MyPage() { > > add(new TextArea("textArea", new PropertyModel(this, > > "currentSnippet.text"); > > > > add(new Button("load") { > > public void onSubmit() { > > currentSnippet = // load snippet from db. > > } > > }); > > } > > } > > > > The model ensure that the textArea is updated when currentSnipped is > > changed. > > > > > 3. In order for my Panel to notify the enclosing WebPage instance > > > that the database has been updated, I wrote a simple > > listener for > > > the Panel. Is there a way to do this that makes more sense > > since > > > I have both the list of objects and the editor on the same > > page? > > > > > You can call the method on panel directly, why a need of special > > interface? But again, you should use model and to to have update the > > components manually. > > > > http://www.wicket-wiki.org.uk/wiki/index.php/Models > > > > -Matej > > > > > > > > > Thanks in advance! > > > > > > Karl M. Davis > > > > > > > > > *HtmlSnippetDemo.html* > > > > > > <?xml version="1.0" encoding="UTF-8"?> > > > > > > <html xmlns="http://www.w3.org/1999/xhtml" > > > > > > > <head> > > > > > > <title>DOH Tech Demos - HtmlSnippetDemo</title> > > > > > > <link rel="Stylesheet" type="text/css" > > href="./style/base-style.css"/> > > > > > > </head> > > > > > > <body> > > > > > > <form wicket:id="frmEditSnippets"> > > > > > > <select wicket:id="selectSnippets"> > > > > > > <option>snip1Id</option> > > > > > > <option>snip2Id</option> > > > > > > </select> > > > > > > <input wicket:id="btnLoad" type="submit" value="Load"/> > > > > > > <input wicket:id="btnNew" type="submit" value="New"/> > > > > > > <input wicket:id="btnDelete" type="submit" value="Delete"/> > > > > > > </form> > > > > > > <hr/> > > > > > > <div wicket:id="htmlSnippetEditor"> > > > > > > </div> > > > > > > </body> > > > > > > </html> > > > > > > > > > *HtmlSnippetDemo.java* > > > > > > public class HtmlSnippetDemo extends WebPage implements > > > > > > HtmlSnippetEditorPanelListener > > > > > > { > > > > > > // Constants > > > > > > private static final long serialVersionUID = 4503823674445131873L; > > > > > > > > > > > > // Member Variables > > > > > > private final ArrayList<String> listSnippetIds = new > > ArrayList<String>(); > > > > > > private final PageModel pageModel = new PageModel(); > > > > > > private HtmlSnippetEditorPanel editorPanel; > > > > > > private HtmlSnippet snippetBeingEdited; > > > > > > > > > > > > /** > > > > > > * Constructor > > > > > > */ > > > > > > public HtmlSnippetDemo() > > > > > > { > > > > > > setModel(new CompoundPropertyModel(pageModel)); > > > > > > > > > > > > // Create the form and add it to the page > > > > > > Form frmEdit = new Form("frmEditSnippets"); > > > > > > this.add(frmEdit); > > > > > > > > > > > > // Load the list of snippets > > > > > > this.updateSnippetList(); > > > > > > > > > > > > // Add the buttons to the form > > > > > > frmEdit.add(new Button("btnLoad") { > > > > > > @Override > > > > > > protected void onSubmit() > > > > > > { > > > > > > super.onSubmit(); > > > > > > > > > > > > JpoxDataAccess da = new JpoxDataAccess(); > > > > > > snippetBeingEdited = new HtmlSnippet(); > > > > > > > > > snippetBeingEdited.setDatastoreId (pageModel.selectSnippets); > > > > > > snippetBeingEdited = > > da.getBoById(snippetBeingEdited, > > > > > > FetchGroups.DEFAULT, 1); > > > > > > > > editorPanel.setHtmlSnippetAsModel(snippetBeingEdited); > > > > > > } > > > > > > }); > > > > > > frmEdit.add(new Button("btnNew") { > > > > > > @Override > > > > > > protected void onSubmit() > > > > > > { > > > > > > super.onSubmit(); > > > > > > > > > > > > snippetBeingEdited = new HtmlSnippet(); > > > > > > > > editorPanel.setHtmlSnippetAsModel(snippetBeingEdited); > > > > > > } > > > > > > }); > > > > > > frmEdit.add(new Button("btnDelete")); > > > > > > > > > > > > // Add the Editor panel to the page > > > > > > editorPanel = new > > HtmlSnippetEditorPanel("htmlSnippetEditor"); > > > > > > editorPanel.addListener (this); > > > > > > add(editorPanel); > > > > > > > > > > > > // Add the ListChoice to the form > > > > > > frmEdit.add(new ListChoice("selectSnippets", > > listSnippetIds)); > > > > > > } > > > > > > > > > > > > /** > > > > > > * Updates the list of available snippets. Does not notify any > > > components using the list as a model. > > > > > > */ > > > > > > private void updateSnippetList() > > > > > > { > > > > > > listSnippetIds.clear(); > > > > > > > > > > > > JpoxDataAccess da = new JpoxDataAccess(); > > > > > > for (Object objCurSnippet : > > da.getBoExtent(HtmlSnippet.class)) > > > > > > listSnippetIds.add(((HtmlSnippet) > > > objCurSnippet).getDatastoreId()); > > > > > > } > > > > > > > > > > > > /** > > > > > > * Simple model for the page's current state. > > > > > > * > > > > > > * @author Karl M. Davis > > > > > > */ > > > > > > private final class PageModel implements Serializable > > > > > > { > > > > > > // Constants > > > > > > private static final long serialVersionUID = > > 1938476569495674967L; > > > > > > > > > > > > public String selectSnippets = null; > > > > > > public String txaEditSnippet = null; > > > > > > } > > > > > > > > > > > > /* (non-Javadoc) > > > > > > * @see > > > > > > > simplepersistence.davis.demos.HtmlSnippetEditorPanel.HtmlSnippetEditorPanelListener#snippetSaved(simplepersistence.davis.model.HtmlSnippet > > ) > > > > > > */ > > > > > > public void snippetSaved(HtmlSnippet snippetAfterSave) > > > > > > { > > > > > > updateSnippetList(); > > > > > > } > > > > > > } > > > > > > > > > *HtmlSnippetEditorPanel.html* > > > > > > <html xmlns:wicket="http://wicket.sourceforge.net/"> > > > > > > <wicket:head> > > > > > > <link wicket:id="editorPanelCss" rel="Stylesheet" type="text/css" > > > href="./style/HtmlSnippetEditorPanel.css"/> > > > > > > </wicket:head> > > > > > > <wicket:panel> > > > > > > <form wicket:id="htmlSnippetEditorForm"> > > > > > > <fieldset class="aligned"> > > > > > > <legend>Edit Html Snippet</legend> > > > > > > <div class="field"> > > > > > > <label for="datastoreId">Datastore ID:</label> > > > > > > <input wicket:id="datastoreId" id="datastoreId" > > > type="text"></input> > > > > > > </div> > > > > > > <div class="field"> > > > > > > <label for="datastoreTimestamp">Datastore > > > Timestamp:</label> > > > > > > <input wicket:id="datastoreTimestamp" > > > id="datastoreTimestamp" type="text"></input> > > > > > > </div> > > > > > > <div class="field"> > > > > > > <label for="dateCreated">Date Created:</label> > > > > > > <input wicket:id="dateCreated" id="dateCreated" > > > type="text"></input> > > > > > > </div> > > > > > > <div class="field"> > > > > > > <label for="dateModified">Date Modified:</label> > > > > > > <input wicket:id="dateModified" > > id="dateModified" > > > type="text"></input> > > > > > > </div> > > > > > > <div class="field"> > > > > > > <label for="name">Name:</label> > > > > > > <input wicket:id="name" id="name" > > type="text"></input> > > > > > > </div> > > > > > > <div class="field"> > > > > > > <label for="html">Html:</label> > > > > > > <textarea wicket:id="html" id="html"></textarea> > > > > > > </div> > > > > > > <input wicket:id="btnSave" type="submit" value="Save" > > > class="button"/> > > > > > > </fieldset> > > > > > > </form> > > > > > > </wicket:panel> > > > > > > </html> > > > > > > > > > *HtmlSnippetEditorPanel.java* > > > > > > public class HtmlSnippetEditorPanel extends Panel > > > > > > { > > > > > > // Constants > > > > > > private static final long serialVersionUID = 2703782070472627254L; > > > > > > > > > > > > // Member Variables > > > > > > private HtmlSnippet snippetBeingEdited; > > > > > > private final ArrayList<HtmlSnippetEditorPanelListener> > > listeners = > > > new ArrayList<HtmlSnippetEditorPanelListener>(); > > > > > > > > > > > > /** > > > > > > * Constructor. > > > > > > * > > > > > > * @param id the component ID for this panel > > > > > > */ > > > > > > public HtmlSnippetEditorPanel(String id) > > > > > > { > > > > > > super(id); > > > > > > setHtmlSnippetAsModel(new HtmlSnippet()); > > > > > > this.createComponents(); > > > > > > } > > > > > > > > > > > > /** > > > > > > * Constructor. > > > > > > * > > > > > > * @param id the component ID for this panel > > > > > > * @param snippetToEdit the [EMAIL PROTECTED] HtmlSnippet} to > > edit with > > this panel > > > > > > */ > > > > > > public HtmlSnippetEditorPanel(String id, HtmlSnippet > > snippetToEdit) > > > > > > { > > > > > > this(id); > > > > > > setHtmlSnippetAsModel(snippetToEdit); > > > > > > } > > > > > > > > > > > > /** > > > > > > * Sets this component to use the specified [EMAIL PROTECTED] > > HtmlSnippet} as > > > its model. > > > > > > * > > > > > > * @param snippetToEdit the [EMAIL PROTECTED] HtmlSnippet} to use > > as the > > new model > > > > > > */ > > > > > > public void setHtmlSnippetAsModel(HtmlSnippet snippetToEdit) > > > > > > { > > > > > > snippetBeingEdited = snippetToEdit; > > > > > > setModel(new CompoundPropertyModel(snippetToEdit)); > > > > > > } > > > > > > > > > > > > /** > > > > > > * Registers a new HtmlSnippetEditorPanelListener with this panel. > > > > > > * > > > > > > * @param listener the listener to register > > > > > > */ > > > > > > public void addListener(HtmlSnippetEditorPanelListener listener) > > > > > > { > > > > > > listeners.add(listener); > > > > > > } > > > > > > > > > > > > /** > > > > > > * Un-registers the specified HtmlSnippetEditorPanelListener from > > > this panel. > > > > > > * > > > > > > * @param listener the listener to un-register > > > > > > */ > > > > > > public void removeListener(HtmlSnippetEditorPanelListener > > listener) > > > > > > { > > > > > > listeners.remove(listener); > > > > > > } > > > > > > > > > > > > /** > > > > > > * Populates this panel's components. > > > > > > */ > > > > > > protected void createComponents() > > > > > > { > > > > > > WebMarkupContainer css = new > > WebMarkupContainer("editorPanelCss"); > > > > > > add(css); > > > > > > > > > > > > Form htmlSnippetEditorForm = new > > Form("htmlSnippetEditorForm"); > > > > > > add(htmlSnippetEditorForm); > > > > > > > > > > > > TextField datastoreId = new TextField("datastoreId"); > > > > > > datastoreId.setEnabled(false); > > > > > > htmlSnippetEditorForm.add(datastoreId); > > > > > > > > > > > > TextField datastoreTimestamp = new > > TextField("datastoreTimestamp"); > > > > > > datastoreTimestamp.setEnabled (false); > > > > > > htmlSnippetEditorForm.add(datastoreTimestamp); > > > > > > > > > > > > TextField dateCreated = new TextField("dateCreated"); > > > > > > dateCreated.setEnabled (false); > > > > > > htmlSnippetEditorForm.add(dateCreated); > > > > > > > > > > > > TextField dateModified = new TextField("dateModified"); > > > > > > dateModified.setEnabled (false); > > > > > > htmlSnippetEditorForm.add(dateModified); > > > > > > > > > > > > TextField name = new TextField("name"); > > > > > > htmlSnippetEditorForm.add(name); > > > > > > TextArea html = new TextArea("html"); > > > > > > htmlSnippetEditorForm.add(html); > > > > > > > > > > > > Button btnSave = new SaveButton("btnSave"); > > > > > > htmlSnippetEditorForm.add(btnSave); > > > > > > } > > > > > > > > > > > > /** > > > > > > * A Button subclass for the "Save" button which will save the > > > snippet that is currently being edited. > > > > > > * > > > > > > * @author Karl M. Davis > > > > > > */ > > > > > > private class SaveButton extends Button > > > > > > { > > > > > > // Constants > > > > > > private static final long serialVersionUID = > > -7606364912415181595L; > > > > > > > > > > > > /** > > > > > > * Constructor. > > > > > > */ > > > > > > public SaveButton(String id) > > > > > > { > > > > > > super(id); > > > > > > } > > > > > > > > > > > > /* (non-Javadoc) > > > > > > * @see wicket.markup.html.form.Button#onSubmit() > > > > > > */ > > > > > > @Override > > > > > > protected void onSubmit() > > > > > > { > > > > > > JpoxDataAccess da = new JpoxDataAccess(); > > > > > > try > > > > > > { > > > > > > snippetBeingEdited = > > da.saveBo(snippetBeingEdited, > > > > > > FetchGroups.DEFAULT, 1); > > > > > > for (HtmlSnippetEditorPanelListener listener : > > > listeners) > > > > > > listener.snippetSaved(snippetBeingEdited); > > > > > > } > > > > > > catch (TimestampMismatchException e) > > > > > > { > > > > > > error(e.getStackTrace().toString()); > > > > > > } > > > > > > finally > > > > > > { > > > > > > setHtmlSnippetAsModel(snippetBeingEdited); > > > > > > } > > > > > > } > > > > > > } > > > > > > > > > > > > /** > > > > > > * A listener interface that allows objects to recieve events from > > > this panel. > > > > > > * > > > > > > * @author Karl M. Davis > > > > > > */ > > > > > > public interface HtmlSnippetEditorPanelListener > > > > > > { > > > > > > /** > > > > > > * This method is called whenever the editor panel saves an > > > HtmlSnippet. > > > > > > * > > > > > > * @param snippetAfterSave the newly-saved HtmlSnippet > > > > > > */ > > > > > > public void snippetSaved(HtmlSnippet snippetAfterSave); > > > > > > } > > > > > > } > > > > > > > > > > > ------------------------------------------------------------------------ > > > > > > _______________________________________________ > > > Wicket-user mailing list > > > [email protected] > > <mailto:[email protected]> > > > https://lists.sourceforge.net/lists/listinfo/wicket-user > > <https://lists.sourceforge.net/lists/listinfo/wicket-user> > > > > > > > > _______________________________________________ > > Wicket-user mailing list > > [email protected] > > <mailto:[email protected]> > > https://lists.sourceforge.net/lists/listinfo/wicket-user > > > > > > > > ------------------------------------------------------------------------ > > > > _______________________________________________ > > Wicket-user mailing list > > [email protected] > > https://lists.sourceforge.net/lists/listinfo/wicket-user > > > > _______________________________________________ > Wicket-user mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/wicket-user > _______________________________________________ Wicket-user mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/wicket-user
