java - 如何在GWT CellTree中选择父节点时选择所有子节点?

标签 java gwt checkbox tree

我使用了 CellTree,其中在每个父节点和子节点上使用了包含 CheckBoxCellCompositeCell

现在我想在选择父节点时选择所有子节点。我怎样才能实现这个目标?

以下是我的代码。

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);
                        }
                    }
                }
            }
        });
    }

最佳答案

您需要两个 SelectionModel
SelectionChangeHandler 添加到父节点的 SelectionModel 中,并在处理程序中检索父对象的所有子对象并调用 MultiSelectionModel.setSelected(Obj,true)在他们身上。

播放列表和歌曲是这样的:

更新:基于评论:

playListSelectionModel.addSelectionChangerHandler(new SelectionChangeEvent.Handler(SelectionChangeEvent event) {
    ArrayList<PlayList> playLists; // all playlists
    for (PlayList playlist:playlists) {
        boolean isSelected = playlistSelectionModel.isSelected(playlist);
        for (String song : selectedPlaylist.getSongs()) {
           selectionModel.setSelected(song, isSelected);
        } 
    }
}}; 

当 playListSelectionModel 是 SingleSelectionModel 时,此方法有效。如果它是 MultiSelectionModel,您需要两个循环。

关于java - 如何在GWT CellTree中选择父节点时选择所有子节点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10121792/

相关文章:

java - Mockito 不能模拟依赖于 Unmarshaller 的类

java - removeAllViews() 不删除 TableLayout 中的 TableRow 子级

gwt - 在 LinkedIn Oauth 回调上创建了新的 HttpSession

php - 使用 mysql 和 php 的复选框更新多行

android - 检查是否选中了任何复选框

java - 如何防止一个部件在关闭时覆盖另一个部件的位置

java - 如何沿着特定轨迹放置物体?

windows-phone-7 - mgwt 与 GWT Mobile - 平台兼容性

php - 结合 servlet 和 "normal"网络服务器

android - 如何将事件处理程序添加到 Android Listview 中的按钮?