-Igor
On 6/7/06, Matej Knopp
<[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="">>
> </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="">>
> </wicket:head>
>
> <wicket:panel>
>
> <form wicket:id="htmlSnippetEditorForm">
>
> <fieldset class="aligned">
>
> <legend>Edit Html Snippet</legend>
>
> <div class="field">
>
> <label for="" ID:</label>
>
> <input wicket:id="datastoreId" id="datastoreId"
> type="text"></input>
>
> </div>
>
> <div class="field">
>
> <label for="">> Timestamp:</label>
>
> <input wicket:id="datastoreTimestamp"
> id="datastoreTimestamp" type="text"></input>
>
> </div>
>
> <div class="field">
>
> <label for="" Created:</label>
>
> <input wicket:id="dateCreated" id="dateCreated"
> type="text"></input>
>
> </div>
>
> <div class="field">
>
> <label for="" Modified:</label>
>
> <input wicket:id="dateModified" id="dateModified"
> type="text"></input>
>
> </div>
>
> <div class="field">
>
> <label for=""
>
> <input wicket:id="name" id="name" type="text"></input>
>
> </div>
>
> <div class="field">
>
> <label for="">>
> <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]
> 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
