我CellTree
在其中使用了CompositeCell
包含CheckBoxCell
在每个父节点和子节点上的内容。
现在我想在选择父节点时选择所有子节点。我怎样才能做到这一点?
以下是我的代码。
public class CellTreeExample implements EntryPoint {
/**
* A list of songs.
*/
private static class Playlist {
private final String name;
private final List<String> songs = new ArrayList<String>();
public Playlist(String name) {
this.name = name;
}
/**
* Add a song to the playlist.
*
* @param name
* the name of the song
*/
public void addSong(String name) {
songs.add(name);
}
public String getName() {
return name;
}
/**
* Return the list of songs in the playlist.
*/
public List<String> getSongs() {
return songs;
}
}
/**
* A composer of classical music.
*/
private static class Composer {
private final String name;
private final List<Playlist> playlists = new ArrayList<Playlist>();
public Composer(String name) {
this.name = name;
}
/**
* Add a playlist to the composer.
*
* @param playlist
* the playlist to add
*/
public Playlist addPlaylist(Playlist playlist) {
playlists.add(playlist);
return playlist;
}
public String getName() {
return name;
}
/**
* Return the rockin' playlist for this composer.
*/
public List<Playlist> getPlaylists() {
return playlists;
}
}
/**
* The model that defines the nodes in the tree.
*/
private static class CustomTreeModel implements TreeViewModel {
private final List<Composer> composers;
/**
* This selection model is shared across all leaf nodes. A selection
* model can also be shared across all nodes in the tree, or each set of
* child nodes can have its own instance. This gives you flexibility to
* determine how nodes are selected.
*/
private MultiSelectionModel<String> selectionModel = new MultiSelectionModel<String>();
private MultiSelectionModel<Playlist> playlistSelectionModel = new MultiSelectionModel<Playlist>();
private MultiSelectionModel<Composer> composerSelectionModel = new MultiSelectionModel<Composer>();
private final Cell<String> contactCell;
static List<HasCell<String, ?>> hasCells = new ArrayList<HasCell<String, ?>>();
private final Cell<Playlist> playlistCell;
static List<HasCell<Playlist, ?>> playlistHasCells = new ArrayList<HasCell<Playlist, ?>>();
private final Cell<Composer> composerCell;
static List<HasCell<Composer, ?>> composerHasCells = new ArrayList<HasCell<Composer, ?>>();
public CustomTreeModel(final MultiSelectionModel<String> selectionModel,final MultiSelectionModel<Playlist> playlistSelectionModel,final MultiSelectionModel<Composer> composerSelectionModel) {
this.selectionModel = selectionModel;
this.playlistSelectionModel = playlistSelectionModel;
this.composerSelectionModel = composerSelectionModel;
// Create a database of information.
composers = new ArrayList<Composer>();
// Add compositions by Beethoven.
{
Composer beethoven = new Composer("Beethoven");
composers.add(beethoven);
Playlist concertos = beethoven.addPlaylist(new Playlist("Concertos"));
concertos.addSong("No. 1 - C");
concertos.addSong("No. 2 - B-Flat Major");
concertos.addSong("No. 3 - C Minor");
concertos.addSong("No. 4 - G Major");
concertos.addSong("No. 5 - E-Flat Major");
Playlist quartets = beethoven.addPlaylist(new Playlist("Quartets"));
quartets.addSong("Six String Quartets");
quartets.addSong("Three String Quartets");
quartets.addSong("Grosse Fugue for String Quartets");
Playlist sonatas = beethoven.addPlaylist(new Playlist("Sonatas"));
sonatas.addSong("Sonata in A Minor");
sonatas.addSong("Sonata in F Major");
Playlist symphonies = beethoven.addPlaylist(new Playlist("Symphonies"));
symphonies.addSong("No. 2 - D Major");
symphonies.addSong("No. 2 - D Major");
symphonies.addSong("No. 3 - E-Flat Major");
symphonies.addSong("No. 4 - B-Flat Major");
symphonies.addSong("No. 5 - C Minor");
symphonies.addSong("No. 6 - F Major");
symphonies.addSong("No. 7 - A Major");
symphonies.addSong("No. 8 - F Major");
symphonies.addSong("No. 9 - D Minor");
}
// Add compositions by Brahms.
{
Composer brahms = new Composer("Brahms");
composers.add(brahms);
Playlist concertos = brahms.addPlaylist(new Playlist("Concertos"));
concertos.addSong("Violin Concerto");
concertos.addSong("Double Concerto - A Minor");
concertos.addSong("Piano Concerto No. 1 - D Minor");
concertos.addSong("Piano Concerto No. 2 - B-Flat Major");
Playlist quartets = brahms.addPlaylist(new Playlist("Quartets"));
quartets.addSong("Piano Quartet No. 1 - G Minor");
quartets.addSong("Piano Quartet No. 2 - A Major");
quartets.addSong("Piano Quartet No. 3 - C Minor");
quartets.addSong("String Quartet No. 3 - B-Flat Minor");
Playlist sonatas = brahms.addPlaylist(new Playlist("Sonatas"));
sonatas.addSong("Two Sonatas for Clarinet - F Minor");
sonatas.addSong("Two Sonatas for Clarinet - E-Flat Major");
Playlist symphonies = brahms.addPlaylist(new Playlist("Symphonies"));
symphonies.addSong("No. 1 - C Minor");
symphonies.addSong("No. 2 - D Minor");
symphonies.addSong("No. 3 - F Major");
symphonies.addSong("No. 4 - E Minor");
}
// Add compositions by Mozart.
{
Composer mozart = new Composer("Mozart");
composers.add(mozart);
Playlist concertos = mozart.addPlaylist(new Playlist("Concertos"));
concertos.addSong("Piano Concerto No. 12");
concertos.addSong("Piano Concerto No. 17");
concertos.addSong("Clarinet Concerto");
concertos.addSong("Violin Concerto No. 5");
concertos.addSong("Violin Concerto No. 4");
}
hasCells.add(new HasCell<String, Boolean>() {
private CheckboxCell cell = new CheckboxCell(true, false){
/* (non-Javadoc)
* @see com.google.gwt.cell.client.CheckboxCell#render(com.google.gwt.cell.client.Cell.Context, java.lang.Boolean, com.google.gwt.safehtml.shared.SafeHtmlBuilder)
*/
@Override
public void render(Context context, Boolean value, SafeHtmlBuilder sb) {
// TODO Auto-generated method stub
super.render(context, value, sb);
}
};
public Cell<Boolean> getCell() {
return cell;
}
public FieldUpdater<String, Boolean> getFieldUpdater() {
return null;
}
public Boolean getValue(String object) {
return selectionModel.isSelected(object);
}
});
contactCell = new CompositeCell<String>(hasCells){
/* @Override
public void render(Context context, String value, SafeHtmlBuilder sb) {
System.out.println("STRING...."+value+" ....");
//sb.appendHtmlConstant("<table><tbody><tr>");
sb.appendHtmlConstant(value);
super.render(context, value, sb);
//sb.appendHtmlConstant(value+"</tr></tbody></table>");
}*/
@Override
protected Element getContainerElement(Element parent) {
// Return the first TR element in the table.
return parent.getFirstChildElement().getFirstChildElement().getFirstChildElement();
}
@Override
protected <X> void render(Context context, String value,
SafeHtmlBuilder sb, HasCell<String, X> hasCell) {
Cell<X> cell = hasCell.getCell();
cell.render(context, hasCell.getValue(value), sb);
sb.appendHtmlConstant(value);
//sb.appendHtmlConstant("</td>");
}
};
playlistHasCells.add(new HasCell<Playlist, Boolean>() {
private CheckboxCell cell = new CheckboxCell(true, false){
/* (non-Javadoc)
* @see com.google.gwt.cell.client.CheckboxCell#render(com.google.gwt.cell.client.Cell.Context, java.lang.Boolean, com.google.gwt.safehtml.shared.SafeHtmlBuilder)
*/
@Override
public void render(Context context, Boolean value, SafeHtmlBuilder sb) {
// TODO Auto-generated method stub
super.render(context, value, sb);
}
};
public Cell<Boolean> getCell() {
return cell;
}
public FieldUpdater<Playlist, Boolean> getFieldUpdater() {
return null;
}
public Boolean getValue(Playlist object) {
return playlistSelectionModel.isSelected(object);
}
});
playlistCell = new CompositeCell<Playlist>(playlistHasCells){
@Override
protected Element getContainerElement(Element parent) {
// Return the first TR element in the table.
return parent.getFirstChildElement().getFirstChildElement().getFirstChildElement();
}
@Override
protected <X> void render(Context context, Playlist value,
SafeHtmlBuilder sb, HasCell<Playlist, X> hasCell) {
Cell<X> cell = hasCell.getCell();
cell.render(context, hasCell.getValue(value), sb);
sb.appendHtmlConstant(value.getName());
//sb.appendHtmlConstant("</td>");
}
};
composerHasCells.add(new HasCell<Composer, Boolean>() {
private CheckboxCell cell = new CheckboxCell(true, false){
/* (non-Javadoc)
* @see com.google.gwt.cell.client.CheckboxCell#render(com.google.gwt.cell.client.Cell.Context, java.lang.Boolean, com.google.gwt.safehtml.shared.SafeHtmlBuilder)
*/
@Override
public void render(Context context, Boolean value, SafeHtmlBuilder sb) {
// TODO Auto-generated method stub
super.render(context, value, sb);
}
};
public Cell<Boolean> getCell() {
return cell;
}
public FieldUpdater<Composer, Boolean> getFieldUpdater() {
return null;
}
public Boolean getValue(Composer object) {
return composerSelectionModel.isSelected(object);
}
});
composerCell = new CompositeCell<Composer>(composerHasCells){
@Override
protected Element getContainerElement(Element parent) {
// Return the first TR element in the table.
return parent.getFirstChildElement().getFirstChildElement().getFirstChildElement();
}
@Override
protected <X> void render(Context context, Composer value,
SafeHtmlBuilder sb, HasCell<Composer, X> hasCell) {
Cell<X> cell = hasCell.getCell();
cell.render(context, hasCell.getValue(value), sb);
sb.appendHtmlConstant(value.getName());
//sb.appendHtmlConstant("</td>");
}
};
}
/**
* Get the {@link NodeInfo} that provides the children of the specified
* value.
*/
public <T> NodeInfo<?> getNodeInfo(T value) {
if (value == null) {
// LEVEL 0.
// We passed null as the root value. Return the composers.
// Create a data provider that contains the list of composers.
ListDataProvider<Composer> dataProvider = new ListDataProvider<CellTreeExample.Composer>(composers);
// Create a cell to display a composer.
Cell<Composer> cell = new AbstractCell<Composer>() {
@Override
public void render(Context context, Composer value, SafeHtmlBuilder sb) {
if (value != null) {
sb.appendEscaped(value.getName());
}
}
};
// Return a node info that pairs the data provider and the cell.
return new DefaultNodeInfo<Composer>(dataProvider, composerCell);
} else if (value instanceof Composer) {
// LEVEL 1.
// We want the children of the composer. Return the playlists.
ListDataProvider<Playlist> dataProvider = new ListDataProvider<Playlist>(((Composer) value)
.getPlaylists());
Cell<Playlist> cell = new AbstractCell<Playlist>() {
@Override
public void render(Context context, Playlist value, SafeHtmlBuilder sb) {
if (value != null) {
sb.appendEscaped(value.getName());
}
}
};
return new DefaultNodeInfo<Playlist>(dataProvider, playlistCell);
} else if (value instanceof Playlist) {
// LEVEL 2 - LEAF.
// We want the children of the playlist. Return the songs.
ListDataProvider<String> dataProvider = new ListDataProvider<String>(((Playlist) value).getSongs());
/*CellList<String> cellList = new CellList<String>(contactCell);
dataProvider.addDataDisplay(cellList);*/
// Use the shared selection model.
return new DefaultNodeInfo<String>(dataProvider, contactCell, selectionModel, null);
}
return null;
}
/**
* Check if the specified value represents a leaf node. Leaf nodes
* cannot be opened.
*/
public boolean isLeaf(Object value) {
// The leaf nodes are the songs, which are Strings.
if (value instanceof String) {
return true;
}
return false;
}
}
public void onModuleLoad() {
final MultiSelectionModel<String> selectionModel =
new MultiSelectionModel<String>();
final MultiSelectionModel<Playlist> playlistSelectionModel =
new MultiSelectionModel<Playlist>();
final MultiSelectionModel<Composer> composerSelectionModel =
new MultiSelectionModel<Composer>();
// Create a model for the tree.
TreeViewModel model = new CustomTreeModel(selectionModel,playlistSelectionModel,composerSelectionModel);
/*
* Create the tree using the model. We use <code>null</code> as the
* default value of the root node. The default value will be passed to
* CustomTreeModel#getNodeInfo();
*/
CellTree tree = new CellTree(model, null);
tree.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
// Open the first playlist by default.
TreeNode rootNode = tree.getRootTreeNode();
TreeNode firstPlaylist = rootNode.setChildOpen(0, true);
firstPlaylist.setChildOpen(0, true);
// Add the tree to the root layout panel.
RootLayoutPanel.get().add(tree);
}
}
我的处理程序代码是:
playlistSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
@Override
public void onSelectionChange(SelectionChangeEvent event) {
Set<Playlist> playlistSet = playlistSelectionModel.getSelectedSet();
Iterator<Playlist> itr = playlistSet.iterator();
while (itr.hasNext()) {
Playlist selectedPlaylist = itr.next();
System.out.println("sel: " + selectedPlaylist.getName());
if (selectedPlaylist != null){
for (String song : selectedPlaylist.getSongs()) {
selectionModel.setSelected(song, true);
}
}
}
}
});
composerSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
@Override
public void onSelectionChange(SelectionChangeEvent event) {
Set<Composer> composerSet = composerSelectionModel.getSelectedSet();
Iterator<Composer> itr = composerSet.iterator();
while (itr.hasNext()) {
Composer selectedComposer = itr.next();
if (selectedComposer != null) {
for (Playlist playlist : selectedComposer.getPlaylists()) {
playlistSelectionModel.setSelected(playlist, true);
}
}
}
}
});
}