Java tutorial
/* * Licensed 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 cc.alcina.framework.gwt.client.objecttree; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import com.google.gwt.event.logical.shared.SelectionEvent; import com.google.gwt.event.logical.shared.SelectionHandler; import com.google.gwt.user.client.ui.ComplexPanel; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HasVerticalAlignment; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.Widget; import cc.alcina.framework.common.client.util.CommonUtils; import cc.alcina.framework.common.client.util.LooseContextInstance; import cc.alcina.framework.gwt.client.logic.RenderContext; import cc.alcina.framework.gwt.client.widget.ToggleLink; import cc.alcina.framework.gwt.client.widget.UsefulWidgetFactory; import cc.alcina.framework.gwt.client.widget.layout.LayoutEvents; /** * * @author Nick Reddel */ public class ObjectTreeExpandableGridRenderer extends ObjectTreeGridRenderer { public static final String MIN_CUSTOMISER_WIDTH = "MIN_CUSTOMISER_WIDTH"; public static final String DEFAULT_SECTION_NAME = "DEFAULT_SECTION_NAME"; private boolean useExpandableWidgets = true; public boolean isUseExpandableWidgets() { return useExpandableWidgets; } public void setUseExpandableWidgets(boolean useExpandableWidgets) { this.useExpandableWidgets = useExpandableWidgets; } @Override protected void renderToPanel(TreeRenderable renderable, ComplexPanel cp, int depth, boolean soleChild, RenderContext renderContext, TreeRenderer parent) { super.renderToPanel(renderable, cp, depth, soleChild, renderContext, parent); if (depth == 0) { cp.remove(ft); if (useExpandableWidgets) { for (Integer level1Row : level1Rows.keySet()) { Widget level1ContentWidget = level1Rows.get(level1Row); TreeRenderer renderer = ObjectTreeExpandableGridRenderer.this.level1ContentRendererMap .get(level1ContentWidget); if (renderer.isAlwaysExpanded()) { continue; } final ExpandableWidgetWithRendererWrapper expandableWidgetWrapper = new ExpandableWidgetWithRendererWrapper( level1ContentWidget, renderer, renderContext); ft.setWidget(level1Row, 1, expandableWidgetWrapper); ft.setWidget(level1Row, colCountMax + 1, new ToggleLink("[Change]", "[Finished]", new SelectionHandler<Integer>() { public void onSelection(SelectionEvent<Integer> event) { expandableWidgetWrapper.showExpanded(event.getSelectedItem() == 0); LayoutEvents.get().fireDeferredGlobalRelayout(); } })); cellFormatter.setVerticalAlignment(level1Row, colCountMax + 1, HasVerticalAlignment.ALIGN_TOP); } } colCountMax += level1Rows.isEmpty() ? 0 : 1; // sort later String section = null; int rowShift = 0; String defaultSectionName = renderContext.getString(DEFAULT_SECTION_NAME); for (Integer i : level1RendererRows.keySet()) { TreeRenderer renderer = level1RendererRows.get(i); String rs = renderer.section(); rs = rs == null ? defaultSectionName : rs; if (!CommonUtils.equalsWithNullEquality(rs, section)) { section = rs; int rowInsert = i + (rowShift++); ft.insertRow(rowInsert); ft.setWidget(rowInsert, 0, UsefulWidgetFactory.mediumTitleWidget(section)); cellFormatter.setColSpan(rowInsert, 0, colCountMax); } } cp.add(ft); } return; } public static class HalfBindableDisplayer extends Composite implements PropertyChangeListener { private Label label; private final TreeRenderer renderer; public HalfBindableDisplayer(TreeRenderer renderer) { this.renderer = renderer; this.label = new Label(); initWidget(label); } public void propertyChange(PropertyChangeEvent evt) { updateText(); } private void updateText() { String text = renderer.renderableText(); boolean empty = CommonUtils.isNullOrEmpty(text); if (empty) { text = renderer.emptyChildText(); label.addStyleName("italic"); } else { label.removeStyleName("italic"); } label.setText(text); } @Override protected void onAttach() { updateText(); renderer.getRenderable().addPropertyChangeListener(this); super.onAttach(); } @Override protected void onDetach() { renderer.getRenderable().removePropertyChangeListener(this); super.onDetach(); } } class ExpandableWidgetWithRendererWrapper extends Composite { private final Widget level1ContentWidget; private FlowPanel fp; private HalfBindableDisplayer bindableDisplayer; public ExpandableWidgetWithRendererWrapper(Widget level1ContentWidget, TreeRenderer renderer, LooseContextInstance renderContext) { this.level1ContentWidget = level1ContentWidget; this.fp = new FlowPanel(); this.bindableDisplayer = new HalfBindableDisplayer(renderer); String minWidth = renderContext.getString(ObjectTreeExpandableGridRenderer.MIN_CUSTOMISER_WIDTH); if (minWidth != null) { bindableDisplayer.setWidth(minWidth); } fp.add(bindableDisplayer); fp.add(level1ContentWidget); showExpanded(false); initWidget(fp); } private void showExpanded(boolean b) { level1ContentWidget.setVisible(b); bindableDisplayer.setVisible(!b); bindableDisplayer.updateText(); } } }