I had a similar need. I wanted a panel that
would display several arbitrary sub-panels
side-by-side:
abstract public class HorizontalPanelGrouper extends
Panel{
public HorizontalPanelGrouper(
String id ) {
super(id);
add(
"wicketIdForPanel1", createPanel1("wicketIdForPanel1") ); //
"wicketIdForPanel1" matches HTML
file
add(
"wicketIdForPanel2", createPanel1("wicketIdForPanel2") ); //
"wicketIdForPanel2" matches HTML
file
add(
"wicketIdForPanel3", createPanel1("wicketIdForPanel3") ); //
"wicketIdForPanel3" matches HTML file
}
abstract Panel createPanel1(String
id);
abstract
Panel createPanel2(String id);
abstract
Panel createPanel3(String
id);
}
Whenever I needed my
panel-of-panels I would instantiate an anonymous subclass that overrode the
createPanelX methods:
Panel p = new
HorizontalPanelGrouper(wicketIdForContainerPanel)
{
Panel
createPanel1(String id) {
return
new SomePanelClass( id,
...);
}
Panel
createPanel2(String id) {
return
new AnotherPanelClass( id,
...);
}
Panel
createPanel3(String id) {
return
new YetAnotherPanelClass( id,
...);
}
}
This way, I didn't have
to remember the actual wicket:id used by the HorizontalPanelGrouper's HTML file
when creating sub-panels for the HorizontalPanelGroup
object.
If I wanted to modify
the layout, all I had to do was create a trivial subclass (i.e. one which
extended the base class without changing or adding anything at the java leve),
but associated with a new HTML
file.
If you wanted a variable
number of sub-panels, instead of abstract methods you could have implement some
of the sub-panels to be trivially empty panels. Alternately, you could
have HorizontalPanelGrouper implement those methods with empty invisible panels
as defaults. Then you need override only some of the panel-creating
functions.
The same approach could
be used if you wanted a panel containing a ListView of sub-panels:
public class
PanelList_Panel extends Panel
{
public PanelList_Panel(String id) {
super(id);
public PanelList_Panel(String id) {
super(id);
add(
new ListView("panelList", createPanelList("panelListElement") ) {
// literal strings are from HTML
file
protected void populateItem(ListItem listItem) {
listItem.add( (Panel) listItem.getModelObject() );
}
}
);
}
protected void populateItem(ListItem listItem) {
listItem.add( (Panel) listItem.getModelObject() );
}
}
);
}
abstract
List<Panel> createPanelList( String id
);
}
}
When using
PanelList_Panel I would create an anonymous subclass that implemented the
abstract method:
Panel p = new
PanelList_Panel( wicketIdForAggregatorPanel )
{
public
List<Panel> createPanelList( String id )
{
...CREATE A
BUNCH OF PANELS USING id AND ADD THEM TO A java.util.List AND RETURN
IT
}
}
When building
components, my natural inclination is to make them configurable via constructor
parameters and methods to be called post-construction. With Wicket,
however, I frequently had to design my components to accept configuration via
the overriding of abstract or default methods by anonymous subclasses. It
felt weird, but eventually I got used to it. I was a functional programmer
in a past life, and it might have felt more natural if I could have passed
functions (like C# delegates) as values to my constructors, but Java doesn't
make that easy.
Alternatively, I suppose
I could have built helper classes much like Swing's event-handler classes.
The helper classes could have contained the abstract methods, and I could have
passed concrete subclasses to my component constructors. But I didn't want
to have to define seperate helper classes whose only purpose was to contain
overrideable methods.
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Charles A Deal
Sent: Thursday, August 17, 2006 2:44 PM
To: wicket-user@lists.sourceforge.net
Subject: [Wicket-user] Creating Panel to display a list of Panels
I am in the process of attempting to rebuild our non-framework, completely homegrown web application as a Wicket application. So, I am very new to the Wicket way and find myself struggling with different things such as proper page construction techniques for relatively complex data-enabled pages. So far, I have been successful in getting a Wicket app running that resembles our existing app, just a lot cleaner. I am having trouble implementing a GUI comcept that we use quite frequently in our current app.
In our current app, we typically have long pages of data fields available to the user, in an attempt to avoid information overload, we implemented "toggle sections" that hide the contents of a section of the page until the section header or "twistee" is clicked, at which point the contents become visible. This is relatively simple in our app, there are two divs, one for the header (name of section, usually one line) and the other for the contents. The content div is "display:none" when the page loads and when the header is clicked to open, that attribute is removed. Pretty simple.
I know that I could do the same think in the Wicket app, but it didn't seem to take advantage of Wicket's features. So, I am seeking to create the described functionality in a more Wicket-minded way. I am open to suggestions of how YOU would do it, but you'll find my idea below. Mind you, that my way doesn't work...yet.
My idea:
Create a panel called ToggleSectionPanel. If would handle the look-n-feel of the toggle header as well as hold the content that should be shown/hidden.
Given a strutuce like this
WebPage
ContentPanel
ToggleSectionPanel (section 1)
SomeFieldsPanel
SomeOtherFieldsPanel
ToggleSectionPanel (section 2)
EvenMoreFieldsPanel
ContetPanel code initialization snippet
ToggleSectionPanel tsp = new ToggleSectionPanel("togPanel");
tsp.setSectionTitle("Section 1");
tsp.addPanel(new SomeFieldsPanel("panel1"));
tsp.addPanel(new SomeOtherFieldsPanel("panel1"));
add(tsp);
tsp = new ToggleSectionPanel("togPanel2");
tsp.setSectionTitle("Section 2");
tsp.addPanel(new EvenMoreFieldsPanel("panel1"));
add(tsp);
ToggleSectionPanel.html
<wicket:panel>
<table border="0" width="100%" cellspacing="0">
<tr>
<td width="20px">
<img wicket:id="toggleImage" width="17" height="15" border="0" />
</td>
<td class="toggleSectionHeader">
<span wicket:id="sectionTitle">[section title]</span>
</td>
</tr>
</table>
<div wicket:id="panels">
</div>
</wicket:panel>
I thought that I might use a ListView to simply write out the panels, but the problem I encountered was that I was adding a Panel in code (new SomeFieldsPanel("panel1")) but I wasn't referencing the id ("panel1") in the html because the listView's ListItems were named by the index. So, then I thought I could just make a MarkupContainer that would spit out the Panels' markup, but that didn't work either.
public class PanelList extends WebMarkupContainer {
/**
* @see wicket.Component#onRender(wicket.markup.MarkupStream)
*/
@SuppressWarnings("unchecked")
protected void onRender(final MarkupStream markupStream) {
final List<Panel> list = (List) getModelObject();
// Save position in markup stream
final int markupStart = markupStream.getCurrentIndex();
if (list != null) {
for (Panel p : list) {
markupStream.setCurrentIndex(markupStart);
p.renderComponent(markupStream);
}
}
}
I got an error "No Markup found" and it referenced the Panel that was part of the List of Panels.
I know that there is a lot here and I hope that it is coherent, but if anyone can offer me some guidance, it would be MUCH appreciated.
Chuck Deal
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
This is a PRIVATE message. If you are not the intended recipient, please delete without copying and kindly advise us by e-mail of the mistake in delivery. NOTE: Regardless of content, this e-mail shall not operate to bind CSC to any order or other contract unless pursuant to explicit written agreement or government initiative expressly permitting the use of e-mail for such purpose.
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________ Wicket-user mailing list Wicket-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/wicket-user