All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.wicket.extensions.breadcrumb.BreadCrumbBar Maven / Gradle / Ivy

There is a newer version: 10.2.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.wicket.extensions.breadcrumb;

import java.util.ArrayList;
import java.util.List;

import org.apache.wicket.Component;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IDetachable;
import org.apache.wicket.model.LoadableDetachableModel;


/**
 * A component that renders bread crumbs. By default, it renders a horizontal list from left to
 * right (oldest left) with bread crumb links and a ' / ' as a separator, e.g.
 * 
 * 
 * first / second / third
 * 
* *

* Delegates how the bread crumb model works to {@link DefaultBreadCrumbsModel}. *

*

* Override and provide your own markup file if you want to work with other elements, e.g. uls * instead of spans. *

* * @author Eelco Hillenius */ public class BreadCrumbBar extends Panel implements IBreadCrumbModel { /** Default crumb component. */ private static final class BreadCrumbComponent extends Panel { private static final long serialVersionUID = 1L; /** * Construct. * * @param id * Component id * @param separatorMarkup * markup used as a separator between breadcrumbs * @param index * The index of the bread crumb * @param breadCrumbModel * The bread crumb model * @param breadCrumbParticipant * The bread crumb * @param enableLink * Whether the link should be enabled */ public BreadCrumbComponent(final String id, final String separatorMarkup, final long index, final IBreadCrumbModel breadCrumbModel, final IBreadCrumbParticipant breadCrumbParticipant, final boolean enableLink) { super(id); add(new Label("sep", (index > 0) ? separatorMarkup : "").setEscapeModelStrings(false) .setRenderBodyOnly(true)); BreadCrumbLink link = new BreadCrumbLink("link", breadCrumbModel) { private static final long serialVersionUID = 1L; @Override protected IBreadCrumbParticipant getParticipant(final String componentId) { return breadCrumbParticipant; } }; link.setEnabled(enableLink); add(link); link.add(new Label("label", breadCrumbParticipant.getTitle()).setRenderBodyOnly(true)); } } /** * List view for rendering the bread crumbs. */ protected class BreadCrumbsListView extends ListView implements IBreadCrumbModelListener { private static final long serialVersionUID = 1L; private transient boolean dirty = false; private transient int size = 0; /** * Construct. * * @param id * Component id */ public BreadCrumbsListView(final String id) { super(id); setReuseItems(false); setDefaultModel(new LoadableDetachableModel>() { private static final long serialVersionUID = 1L; @Override protected List load() { // save a copy List l = new ArrayList( allBreadCrumbParticipants()); size = l.size(); return l; } }); } @Override public void breadCrumbActivated(final IBreadCrumbParticipant previousParticipant, final IBreadCrumbParticipant breadCrumbParticipant) { signalModelChange(); } @Override public void breadCrumbAdded(final IBreadCrumbParticipant breadCrumbParticipant) { } @Override public void breadCrumbRemoved(final IBreadCrumbParticipant breadCrumbParticipant) { } /** * Signal model change. */ private void signalModelChange() { // else let the listview recalculate it's children immediately; // it was attached, but it needs to go through that again now // as the signaling component attached after this getDefaultModel().detach(); } /** * @see org.apache.wicket.markup.html.list.ListView#onBeforeRender() */ @Override protected void onBeforeRender() { super.onBeforeRender(); if (dirty) { dirty = false; } } @Override protected void populateItem(final ListItem item) { long index = item.getIndex(); IBreadCrumbParticipant breadCrumbParticipant = (IBreadCrumbParticipant)item.getDefaultModelObject(); item.add(newBreadCrumbComponent("crumb", index, size, breadCrumbParticipant)); } } private static final long serialVersionUID = 1L; private final IBreadCrumbModel decorated; /** * Construct. * * @param id * Component id */ public BreadCrumbBar(final String id) { super(id); decorated = new DefaultBreadCrumbsModel(); BreadCrumbsListView breadCrumbsListView = new BreadCrumbsListView("crumbs"); addListener(breadCrumbsListView); add(breadCrumbsListView); } @Override public void addListener(final IBreadCrumbModelListener listener) { decorated.addListener(listener); } @Override public List allBreadCrumbParticipants() { return decorated.allBreadCrumbParticipants(); } @Override public IBreadCrumbParticipant getActive() { return decorated.getActive(); } @Override public void removeListener(final IBreadCrumbModelListener listener) { decorated.removeListener(listener); } @Override public void setActive(final IBreadCrumbParticipant breadCrumbParticipant) { decorated.setActive(breadCrumbParticipant); } /** * Gets whether the current bread crumb should be displayed as a link (e.g. for refreshing) or * as a disabled link (effectively just a label). The latter is the default. Override if you * want different behavior. * * @return Whether the current bread crumb should be displayed as a link; this method returns * false */ protected boolean getEnableLinkToCurrent() { return false; } /** * @return markup used as a separator between breadcrumbs. By default / is used, * but >> is also a popular choice. */ protected String getSeparatorMarkup() { return "/"; } /** * Creates a new bread crumb component. That component will be rendered as part of the bread * crumbs list (which is a <ul> <li> structure). * * @param id * The component id * @param index * The index of the bread crumb * @param total * The total number of bread crumbs in the current model * @param breadCrumbParticipant * the bread crumb * @return A new bread crumb component */ protected Component newBreadCrumbComponent(final String id, final long index, final int total, final IBreadCrumbParticipant breadCrumbParticipant) { boolean enableLink = getEnableLinkToCurrent() || (index < (total - 1)); return new BreadCrumbComponent(id, getSeparatorMarkup(), index, this, breadCrumbParticipant, enableLink); } @Override protected void onDetach() { super.onDetach(); for (IBreadCrumbParticipant crumb : decorated.allBreadCrumbParticipants()) { if (crumb instanceof Component) { ((Component)crumb).detach(); } else if (crumb instanceof IDetachable) { ((IDetachable)crumb).detach(); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy