2009年4月20日星期一

可关闭的Wicket TabbedPanel

Wicket中自带的TabbedPanel是不能关闭的,而在项目中,却要使用可以关闭的Tabs,因此参考Wicket Wiki上的例子,自己实现了一套带关闭图标的TabbedPannel。具体实现方式如下:
第一步:创建一个abstract SimpleAbstractTab类,扩展AbstractTab。
public abstract class SimpleAbstractTab extends AbstractTab {
private String title;
private boolean canBeClosed;

public SimpleAbstractTab(IModel iModel, String title, boolean canBeClosed) {
super(iModel);
this.title = title;
this.canBeClosed = canBeClosed;
}

public String getOngletTitle() {
return this.title;
}

public boolean isCanBeClosed() {
return canBeClosed;
}
}

第二步:创建一个SimpleTabbedPanel,扩展TabbedPanel。

public class SimpleTabbedPanel extends Panel {
private static final long serialVersionUID = 1L;
public static final String TAB_PANEL_ID = "panel";

private String whereAmI;
private final List tabs;

public SimpleTabbedPanel(String id, List tabs) {
super(id, new Model(new Integer(-1)));
add(CSSPackageResource.getHeaderContribution(DefaultStyle.TabbedPanel.getResouceReference()));
this.setOutputMarkupId(true);

if (tabs == null) {
throw new IllegalArgumentException("argument [tabs] cannot be null");
}

this.tabs = tabs;

final IModel tabCount = new AbstractReadOnlyModel() {
private static final long serialVersionUID = 1L;

public Object getObject() {
return new Integer(SimpleTabbedPanel.this.tabs.size());
}
};

WebMarkupContainer tabsContainer = new WebMarkupContainer(
"tabs-container") {
private static final long serialVersionUID = 1L;

protected void onComponentTag(ComponentTag tag) {
super.onComponentTag(tag);
tag.put("class", getTabContainerCssClass());
}
};
add(tabsContainer);

// add the loop used to generate tab names
tabsContainer.add(new Loop("tabs", tabCount) {
private static final long serialVersionUID = 1L;

protected void populateItem(LoopItem item) {
final int index = item.getIteration();

final WebMarkupContainer titleLink = newLink("link", index);

titleLink.add(newTitle("title", SimpleTabbedPanel.this.tabs
.get(index).getOngletTitle(), index));
item.add(titleLink);

final AjaxLink closeLink = newAjaxLink("closeTab", index);
closeLink.add(new Image("closeImg", DefaultImage.TabClosed.getResouceReference()));
if (!SimpleTabbedPanel.this.tabs.get(index).isCanBeClosed())
closeLink.setVisible(false);
item.add(closeLink);
}

protected LoopItem newItem(int iteration) {
return newTabContainer(iteration);
}

});

this.whereAmI = this.tabs.get(0).getOngletTitle();
}

protected LoopItem newTabContainer(int tabIndex) {
return new LoopItem(tabIndex) {
private static final long serialVersionUID = 1L;

protected void onComponentTag(ComponentTag tag) {
super.onComponentTag(tag);
String cssClass = (String) tag.getString("class");
if (cssClass == null) {
cssClass = " ";
}
cssClass += " tab" + getIteration();

if (getIteration() == getSelectedTab()) {
cssClass += " selected";
}
if (getIteration() == getTabs().size() - 1) {
cssClass += " last";
}
tag.put("class", cssClass.trim());
}

};
}

protected void onBeforeRender() {
super.onBeforeRender();
if (!hasBeenRendered() && getSelectedTab() == -1) {
// select the first tab by default
setSelectedTab(0);
}
}

protected String getTabContainerCssClass() {
return "tab-row";
}

public final List getTabs() {
return tabs;
}

protected Component newTitle(String titleId, String title, int index) {
return new Label(titleId, title);
}

public void newTab(AjaxRequestTarget target, SimpleAbstractTab tab) {
this.tabs.add(tab);
this.setSelectedTab(this.tabs.size()-1);
target.addComponent(this);
}

public void removeTab(AjaxRequestTarget target, int index) {
String titleDeletedTab = this.tabs.get(index).getOngletTitle();
this.tabs.remove(index);

if (titleDeletedTab.equals(this.whereAmI)) {
this.setSelectedTab(0);
this.whereAmI = this.tabs.get(0).getOngletTitle();
} else {
this.setSelectedTab(this.findSelectedTab(whereAmI));
}

target.addComponent(this);
}

protected int findSelectedTab(String title) {
int result = 0;
for (int i = 0; i < result =" i;">= tabs.size()) {
throw new IndexOutOfBoundsException();
}

setDefaultModelObject(new Integer(index));

ITab tab = (ITab) tabs.get(index);

Panel panel = tab.getPanel(TAB_PANEL_ID);

if (panel == null) {
throw new WicketRuntimeException(
"ITab.getPanel() returned null. TabbedPanel [" + getPath()
+ "] ITab index [" + index + "]");

}

if (!panel.getId().equals(TAB_PANEL_ID)) {
throw new WicketRuntimeException(
"ITab.getPanel() returned a panel with invalid id ["
+ panel.getId()
+ "]. You must always return a panel with id equal to the provided panelId parameter. TabbedPanel ["
+ getPath() + "] ITab index [" + index + "]");
}

if (get(TAB_PANEL_ID) == null) {
add(panel);
} else {
replace(panel);
}

this.whereAmI = this.tabs.get(index).getOngletTitle();
}

public final int getSelectedTab() {
return ((Integer) getDefaultModelObject()).intValue();
}
}


第三步:同时,创建一个SimpleTabbedPanel.html,页面如下:

[wicket:panel]
[div wicket:id="tabs-container" class="tab-row"]
[ul]
[li wicket:id="tabs"]
[div class="tab"]
[a href="#" wicket:id="link" class="tab-link"][span wicket:id="title"]tab title[/span][/a]
[a href="#" wicket:id="closeTab" class="tab-close"][img wicket:id="closeImg" alt="Close" border=0/][/a]
[/div]
[/li]
[/ul]
[/div]
[div wicket:id="panel" class="tab-panel"]panel[/div]
[/wicket:panel]

第四步:创建一个css文件,并使用一个close的icon。
div.tabpanel div.tab-row ul {
height: 20px;
margin: 0;
padding-left: 10px;
background: url( images/tab_bottom.gif ) repeat-x bottom;
}

div.tabpanel div.tab-row li {
margin: 0;
padding:0 5px 0 0;
display: inline;
list-style-type: none;
}

div.tabpanel div.tab-row div.tab {
float:left;
display:block;
background:#f3f3f3;
padding:5px 7px 4px 20px;
text-decoration:none;
font-weight:bold;
color:#9cf;
border: 1px solid #ccc;
white-space:nowrap;
}

div.tabpanel div.tab-row a.tab-link:link, div.tabpanel div.tab-row a.tab-link:visited {
float: left;
background: #f3f3f3;
font-size: 12px;
line-height: 14px;
font-weight: bold;
padding:5px 10px 4px 10px;
margin-right: 4px;
text-decoration: none;
color: #666;
}

div.tabpanel div.tab-row li.selected a.tab-link:link, div.tabpanel div.tab-row a.tab-link:visited.active {
border-bottom: 1px solid #fff;
background: #fff;
color: #000;
}

div.tabpanel div.tab-row a.tab-link:hover {
background: #fff;
}

div.tabpanel div.tab-row a.tab-close:hover {
background: #B9D4E8;
}

第五步:实现几个panel,如FirstTab等都是自己任意实现的Panel,调用SimpleTabbedPanel

//tabs
final List tabs = new ArrayList();
tabs.add(new SimpleAbstractTab(new Model("first tab"), "simple tab1", true) {
@Override
public Panel getPanel(final String panelId) {
return new FirstTab(panelId);
}
});
final SimpleTabbedPanel tabbedPanel = new SimpleTabbedPanel("tabs", tabs);
add(tabbedPanel);

// The AjaxLink to new tab
add(new AjaxLink("newTab"){
public void onClick(AjaxRequestTarget target) {
tabbedPanel.newTab(target, new SimpleAbstractTab(new Model("first tab"), "new Tab", true) {
@Override
public Panel getPanel(final String panelId) {
return new NewTab(panelId);
}
});
}
});



没有评论:

发表评论