Recently I wanted a component(table like) which expands column wise.
I googled a bit but found no appropirate component. So decided to build my own panel which can expand column-wise.
Thats the beauty of wicket! You can create custom components by using more than one out of box components easily.
So for my proto, I created two models, Row and Column.
A custom panel which takes up number of rows required in the constructor. And columns can be added to / removed from using defined
methods.
For example, I have made each column to have a radio button which has a radio group binded to it horizontally.
It can be expanded very easily to contain multiple copies of columns.
Let us see the code.
Row.java
import java.io.Serializable;
/**
* Row Model
* @author Srikanth NT
*/
public class Row implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private String desc;
public Row(final int id, final String desc) {
super();
this.id = id;
this.desc = desc;
}
public int getId() {
return id;
}
public void setId(final int id) {
this.id = id;
}
public String getDesc() {
return desc;
}
public void setDesc(final String desc) {
this.desc = desc;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((desc == null) ? 0 : desc.hashCode());
result = prime * result + id;
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Row other = (Row) obj;
if (desc == null) {
if (other.desc != null) {
return false;
}
} else if (!desc.equals(other.desc)) {
return false;
}
if (id != other.id) {
return false;
}
return true;
}
@Override
public String toString() {
return "Row [" + id + ":" + desc + "]";
}
}
Column.java
import java.io.Serializable;
/**
* Column Model.
*
* @author Srikanth NT
*/
public class Column implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private String desc;
public Column(final int id, final String desc) {
super();
this.id = id;
this.desc = desc;
}
public int getId() {
return id;
}
public void setId(final int id) {
this.id = id;
}
public String getDesc() {
return desc;
}
public void setDesc(final String desc) {
this.desc = desc;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((desc == null) ? 0 : desc.hashCode());
result = prime * result + id;
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Column other = (Column) obj;
if (desc == null) {
if (other.desc != null) {
return false;
}
} else if (!desc.equals(other.desc)) {
return false;
}
if (id != other.id) {
return false;
}
return true;
}
@Override
public String toString() {
return "Column [" + id + ":" + desc + "]";
}
}
My custom panel is :
CustomPanel.javaimport java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.wicket.Component;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Radio;
import org.apache.wicket.markup.html.form.RadioGroup;
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.Model;
/**
* Custom Panel with expanding columns.
*
* @author Srikanth NT
*/
public class CustomPanel extends Panel {
private List<Row> rows;
private Map<Row, List<Column>> elements = new LinkedHashMap<Row, List<Column>>();
private final ListView rowRepeater;
public CustomPanel(final String id, final List<Row> rowsToAdd) {
super(id);
rows = rowsToAdd;
for (Row row : rows) {
elements.put(row, new ArrayList<Column>());
}
rowRepeater = new ListView("rowRepeater", rows) {
private static final long serialVersionUID = 1L;
@Override
protected void populateItem(final ListItem item) {
Row row = (Row) item.getModelObject();
item.add(new Label("rowDesc", row.getDesc()));
final RadioGroup columnSelectionGroup = new RadioGroup("columnSelectionGroup", new Model());
final ListView columnRepeater = new ListView("columnRepeater", elements.get(row)) {
private static final long serialVersionUID = 1L;
@Override
protected void populateItem(final ListItem item) {
Column column = (Column) item.getModelObject();
item.add(new Radio("columnSelection", new Model(column)));
}
};
columnRepeater.setReuseItems(true);
columnSelectionGroup.add(columnRepeater);
item.add(columnSelectionGroup);
}
};
rowRepeater.setReuseItems(true);
add(rowRepeater);
rowRepeater.setOutputMarkupId(true);
}
public void addColumn(final Column column) {
for (Entry<Row, List<Column>> entry : elements.entrySet()) {
if(!entry.getValue().contains(column)) {
entry.getValue().add(entry.getValue().size(), column);
}
}
}
public void removeColumn(final Column column) {
for (Entry<Row, List<Column>> entry : elements.entrySet()) {
while (entry.getValue().contains(column)) {
entry.getValue().remove(column);
}
}
}
public Map<Row, Column> getRowColumnsMapping() {
final Map<Row, Column> rowColumnsMapping = new LinkedHashMap<Row, Column>();
for (final Iterator it = rowRepeater.iterator(); it.hasNext();) {
final ListItem item = (ListItem) it.next();
final Row row = (Row) item.getModelObject();
item.visitChildren(new IVisitor() {
public Object component(final Component component) {
if (component instanceof RadioGroup) {
Column column = (Column) component.getModelObject();
rowColumnsMapping.put(row, column);
}
return CONTINUE_TRAVERSAL;
}
});
}
return rowColumnsMapping;
}
}
And its corresponding html:
CustomPanel.html
<wicket:panel>
<table>
<tr wicket:id="rowRepeater">
<td wicket:id="rowDesc"></td>
<span wicket:id="columnSelectionGroup">
<span wicket:id="columnRepeater">
<td><input type="radio" wicket:id="columnSelection"></td>
</span>
</span>
</tr>
</table>
</wicket:panel>
And now a test page to check my custom component.
CustomTestPage.java
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
/**
* Test Page.
*
* @author Srikanth NT
*/
public class CustomTestPage extends WebPage {
public CustomTestPage() {
final Form columnSelectorForm = new Form("columnSelectorForm");
add(columnSelectorForm);
List<Row> rowList = new ArrayList<Row>();
rowList.add(new Row(1, "Row-1"));
rowList.add(new Row(2, "Row-2"));
final CustomPanel columnSelectorPanel = new CustomPanel("columnSelectorPanel", rowList);
columnSelectorPanel.setOutputMarkupId(true);
columnSelectorForm.add(columnSelectorPanel);
columnSelectorForm.add(new AjaxButton("addColumn1", columnSelectorForm) {
private static final long serialVersionUID = 1L;
@Override
protected void onSubmit(final AjaxRequestTarget target, final Form form) {
target.addComponent(columnSelectorPanel);
Column column = new Column(1, "Column 1");
columnSelectorPanel.addColumn(column);
}
});
columnSelectorForm.add(new AjaxButton("removeColumn1", columnSelectorForm) {
private static final long serialVersionUID = 1L;
@Override
protected void onSubmit(final AjaxRequestTarget target, final Form form) {
target.addComponent(columnSelectorPanel);
Column column = new Column(1, "Column 1");
columnSelectorPanel.removeColumn(column);
}
});
columnSelectorForm.add(new AjaxButton("addColumn2", columnSelectorForm) {
private static final long serialVersionUID = 1L;
@Override
protected void onSubmit(final AjaxRequestTarget target, final Form form) {
target.addComponent(columnSelectorPanel);
Column column = new Column(1, "Column 2");
columnSelectorPanel.addColumn(column);
}
});
columnSelectorForm.add(new AjaxButton("removeColumn2", columnSelectorForm) {
private static final long serialVersionUID = 1L;
@Override
protected void onSubmit(final AjaxRequestTarget target, final Form form) {
target.addComponent(columnSelectorPanel);
Column column = new Column(1, "Column 2");
columnSelectorPanel.removeColumn(column);
}
});
columnSelectorForm.add(new Button("submit") {
@Override
public void onSubmit() {
Map<Row, Column> list = columnSelectorPanel.getRowColumnsMapping();
for (Entry<Row, Column> entry : list.entrySet()) {
System.out.println(entry.getKey() + " is assigned to " + entry.getValue());
}
}
});
}
}
and related html:CustomTestPage.html
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<form wicket:id="columnSelectorForm">
<div style="border: 1px solid blue;">
<table cellpadding="5px">
<tr>
<td>Column 1</td>
<td><input value="Add" wicket:id="addColumn1" type="button" ></td>
<td><input value="Remove" wicket:id="removeColumn1" type="button" ></td>
</tr>
<tr>
<td>Column 2</td>
<td><input value="Add" wicket:id="addColumn2" type="button" ></td>
<td><input value="Remove" wicket:id="removeColumn2" type="button" ></td>
</tr>
</table>
</div>
<div style="border: 1px solid red;">
<span wicket:id="columnSelectorPanel"> </span>
</div>
<input type="submit" value="Submit" wicket:id="submit">
</form>
</body>
</html>
I have used some ajax functionality built into it.
On submit of the form, you would see some log like
Row [1:Row-1] is assigned to Column [1:Column 2]
Row [2:Row-2] is assigned to Column [1:Column 1]
( I have added the column 2 followed by column1.)
I googled a bit but found no appropirate component. So decided to build my own panel which can expand column-wise.
Thats the beauty of wicket! You can create custom components by using more than one out of box components easily.
So for my proto, I created two models, Row and Column.
A custom panel which takes up number of rows required in the constructor. And columns can be added to / removed from using defined
methods.
For example, I have made each column to have a radio button which has a radio group binded to it horizontally.
It can be expanded very easily to contain multiple copies of columns.
Let us see the code.
Row.java
import java.io.Serializable;
/**
* Row Model
* @author Srikanth NT
*/
public class Row implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private String desc;
public Row(final int id, final String desc) {
super();
this.id = id;
this.desc = desc;
}
public int getId() {
return id;
}
public void setId(final int id) {
this.id = id;
}
public String getDesc() {
return desc;
}
public void setDesc(final String desc) {
this.desc = desc;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((desc == null) ? 0 : desc.hashCode());
result = prime * result + id;
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Row other = (Row) obj;
if (desc == null) {
if (other.desc != null) {
return false;
}
} else if (!desc.equals(other.desc)) {
return false;
}
if (id != other.id) {
return false;
}
return true;
}
@Override
public String toString() {
return "Row [" + id + ":" + desc + "]";
}
}
Column.java
import java.io.Serializable;
/**
* Column Model.
*
* @author Srikanth NT
*/
public class Column implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private String desc;
public Column(final int id, final String desc) {
super();
this.id = id;
this.desc = desc;
}
public int getId() {
return id;
}
public void setId(final int id) {
this.id = id;
}
public String getDesc() {
return desc;
}
public void setDesc(final String desc) {
this.desc = desc;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((desc == null) ? 0 : desc.hashCode());
result = prime * result + id;
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Column other = (Column) obj;
if (desc == null) {
if (other.desc != null) {
return false;
}
} else if (!desc.equals(other.desc)) {
return false;
}
if (id != other.id) {
return false;
}
return true;
}
@Override
public String toString() {
return "Column [" + id + ":" + desc + "]";
}
}
My custom panel is :
CustomPanel.javaimport java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.wicket.Component;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Radio;
import org.apache.wicket.markup.html.form.RadioGroup;
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.Model;
/**
* Custom Panel with expanding columns.
*
* @author Srikanth NT
*/
public class CustomPanel extends Panel {
private List<Row> rows;
private Map<Row, List<Column>> elements = new LinkedHashMap<Row, List<Column>>();
private final ListView rowRepeater;
public CustomPanel(final String id, final List<Row> rowsToAdd) {
super(id);
rows = rowsToAdd;
for (Row row : rows) {
elements.put(row, new ArrayList<Column>());
}
rowRepeater = new ListView("rowRepeater", rows) {
private static final long serialVersionUID = 1L;
@Override
protected void populateItem(final ListItem item) {
Row row = (Row) item.getModelObject();
item.add(new Label("rowDesc", row.getDesc()));
final RadioGroup columnSelectionGroup = new RadioGroup("columnSelectionGroup", new Model());
final ListView columnRepeater = new ListView("columnRepeater", elements.get(row)) {
private static final long serialVersionUID = 1L;
@Override
protected void populateItem(final ListItem item) {
Column column = (Column) item.getModelObject();
item.add(new Radio("columnSelection", new Model(column)));
}
};
columnRepeater.setReuseItems(true);
columnSelectionGroup.add(columnRepeater);
item.add(columnSelectionGroup);
}
};
rowRepeater.setReuseItems(true);
add(rowRepeater);
rowRepeater.setOutputMarkupId(true);
}
public void addColumn(final Column column) {
for (Entry<Row, List<Column>> entry : elements.entrySet()) {
if(!entry.getValue().contains(column)) {
entry.getValue().add(entry.getValue().size(), column);
}
}
}
public void removeColumn(final Column column) {
for (Entry<Row, List<Column>> entry : elements.entrySet()) {
while (entry.getValue().contains(column)) {
entry.getValue().remove(column);
}
}
}
public Map<Row, Column> getRowColumnsMapping() {
final Map<Row, Column> rowColumnsMapping = new LinkedHashMap<Row, Column>();
for (final Iterator it = rowRepeater.iterator(); it.hasNext();) {
final ListItem item = (ListItem) it.next();
final Row row = (Row) item.getModelObject();
item.visitChildren(new IVisitor() {
public Object component(final Component component) {
if (component instanceof RadioGroup) {
Column column = (Column) component.getModelObject();
rowColumnsMapping.put(row, column);
}
return CONTINUE_TRAVERSAL;
}
});
}
return rowColumnsMapping;
}
}
And its corresponding html:
CustomPanel.html
<wicket:panel>
<table>
<tr wicket:id="rowRepeater">
<td wicket:id="rowDesc"></td>
<span wicket:id="columnSelectionGroup">
<span wicket:id="columnRepeater">
<td><input type="radio" wicket:id="columnSelection"></td>
</span>
</span>
</tr>
</table>
</wicket:panel>
And now a test page to check my custom component.
CustomTestPage.java
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
/**
* Test Page.
*
* @author Srikanth NT
*/
public class CustomTestPage extends WebPage {
public CustomTestPage() {
final Form columnSelectorForm = new Form("columnSelectorForm");
add(columnSelectorForm);
List<Row> rowList = new ArrayList<Row>();
rowList.add(new Row(1, "Row-1"));
rowList.add(new Row(2, "Row-2"));
final CustomPanel columnSelectorPanel = new CustomPanel("columnSelectorPanel", rowList);
columnSelectorPanel.setOutputMarkupId(true);
columnSelectorForm.add(columnSelectorPanel);
columnSelectorForm.add(new AjaxButton("addColumn1", columnSelectorForm) {
private static final long serialVersionUID = 1L;
@Override
protected void onSubmit(final AjaxRequestTarget target, final Form form) {
target.addComponent(columnSelectorPanel);
Column column = new Column(1, "Column 1");
columnSelectorPanel.addColumn(column);
}
});
columnSelectorForm.add(new AjaxButton("removeColumn1", columnSelectorForm) {
private static final long serialVersionUID = 1L;
@Override
protected void onSubmit(final AjaxRequestTarget target, final Form form) {
target.addComponent(columnSelectorPanel);
Column column = new Column(1, "Column 1");
columnSelectorPanel.removeColumn(column);
}
});
columnSelectorForm.add(new AjaxButton("addColumn2", columnSelectorForm) {
private static final long serialVersionUID = 1L;
@Override
protected void onSubmit(final AjaxRequestTarget target, final Form form) {
target.addComponent(columnSelectorPanel);
Column column = new Column(1, "Column 2");
columnSelectorPanel.addColumn(column);
}
});
columnSelectorForm.add(new AjaxButton("removeColumn2", columnSelectorForm) {
private static final long serialVersionUID = 1L;
@Override
protected void onSubmit(final AjaxRequestTarget target, final Form form) {
target.addComponent(columnSelectorPanel);
Column column = new Column(1, "Column 2");
columnSelectorPanel.removeColumn(column);
}
});
columnSelectorForm.add(new Button("submit") {
@Override
public void onSubmit() {
Map<Row, Column> list = columnSelectorPanel.getRowColumnsMapping();
for (Entry<Row, Column> entry : list.entrySet()) {
System.out.println(entry.getKey() + " is assigned to " + entry.getValue());
}
}
});
}
}
and related html:CustomTestPage.html
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<form wicket:id="columnSelectorForm">
<div style="border: 1px solid blue;">
<table cellpadding="5px">
<tr>
<td>Column 1</td>
<td><input value="Add" wicket:id="addColumn1" type="button" ></td>
<td><input value="Remove" wicket:id="removeColumn1" type="button" ></td>
</tr>
<tr>
<td>Column 2</td>
<td><input value="Add" wicket:id="addColumn2" type="button" ></td>
<td><input value="Remove" wicket:id="removeColumn2" type="button" ></td>
</tr>
</table>
</div>
<div style="border: 1px solid red;">
<span wicket:id="columnSelectorPanel"> </span>
</div>
<input type="submit" value="Submit" wicket:id="submit">
</form>
</body>
</html>
I have used some ajax functionality built into it.
On submit of the form, you would see some log like
Row [1:Row-1] is assigned to Column [1:Column 2]
Row [2:Row-2] is assigned to Column [1:Column 1]
( I have added the column 2 followed by column1.)
1 comment:
zzzzz2018.11.26
jordans
jordan shoes
canada goose outlet
coach outlet
canada goose
valentino shoes
issey miyake
ray ban sunglasses
champion sportswear
christmas presents
Post a Comment