Java tutorial
/* * Copyright (c) 2012-2014 Veniamin Isaias. * * This file is part of web4thejob. * * Web4thejob is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or any later version. * * Web4thejob is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with web4thejob. If not, see <http://www.gnu.org/licenses/>. */ package org.web4thejob.web.panel.base; import org.springframework.util.StringUtils; import org.web4thejob.command.Command; import org.web4thejob.command.CommandAware; import org.web4thejob.command.CommandMerger; import org.web4thejob.command.CommandRenderer; import org.web4thejob.context.ContextUtil; import org.web4thejob.message.Message; import org.web4thejob.message.MessageEnum; import org.web4thejob.setting.SettingAware; import org.web4thejob.setting.SettingEnum; import org.web4thejob.web.panel.Attributes; import org.web4thejob.web.panel.*; import org.web4thejob.web.panel.Panel; import org.web4thejob.web.panel.base.zk.AbstractZkLayoutPanel; import org.web4thejob.web.util.ZkUtil; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.OpenEvent; import org.zkoss.zul.*; import java.io.Serializable; import java.util.*; /** * @author Veniamin Isaias * @since 1.0.0 */ public abstract class AbstractBorderLayoutPanel extends AbstractZkLayoutPanel implements CommandMerger { // ------------------------------ FIELDS ------------------------------ protected static final String REGION_SIZE = "25%"; private static final int DEFAULT_CHILDREN_COUNT = 5; private static final String[] defaultRegionOrder = { Borderlayout.CENTER, Borderlayout.NORTH, Borderlayout.SOUTH, Borderlayout.WEST, Borderlayout.EAST }; private final Borderlayout blayout = new Borderlayout(); private final SelectEventHandler selectHandler = new SelectEventHandler(); @Override public void dispatchMessage(Message message) { if (MessageEnum.TITLE_CHANGED == message.getId() && subpanels.contains(message.getSender())) { super.dispatchMessage(ContextUtil.getMessage(message.getId(), this, message.getArgs())); } else { super.dispatchMessage(message); } } // --------------------------- CONSTRUCTORS --------------------------- protected AbstractBorderLayoutPanel() { ZkUtil.setParentOfChild((Component) base, blayout); blayout.setWidth("100%"); blayout.setVflex("true"); } // ------------------------ INTERFACE METHODS ------------------------ @Override protected void beforePersistencePhase() { if (blayout.getNorth() != null) { setSettingValue(SettingEnum.NORTH_ENABLED, true); setSettingValue(SettingEnum.NORTH_OPEN, blayout.getNorth().isOpen()); setSettingValue(SettingEnum.NORTH_COLLAPSIBLE, blayout.getNorth().isCollapsible()); setSettingValue(SettingEnum.NORTH_SPLITTABLE, blayout.getNorth().isSplittable()); } else { setSettingValue(SettingEnum.NORTH_ENABLED, false); } if (blayout.getSouth() != null) { setSettingValue(SettingEnum.SOUTH_ENABLED, true); setSettingValue(SettingEnum.SOUTH_OPEN, blayout.getSouth().isOpen()); setSettingValue(SettingEnum.SOUTH_COLLAPSIBLE, blayout.getSouth().isCollapsible()); setSettingValue(SettingEnum.SOUTH_SPLITTABLE, blayout.getSouth().isSplittable()); } else { setSettingValue(SettingEnum.SOUTH_ENABLED, false); } if (blayout.getEast() != null) { setSettingValue(SettingEnum.EAST_ENABLED, true); setSettingValue(SettingEnum.EAST_OPEN, blayout.getEast().isOpen()); setSettingValue(SettingEnum.EAST_COLLAPSIBLE, blayout.getEast().isCollapsible()); setSettingValue(SettingEnum.EAST_SPLITTABLE, blayout.getEast().isSplittable()); } else { setSettingValue(SettingEnum.EAST_ENABLED, false); } if (blayout.getWest() != null) { setSettingValue(SettingEnum.WEST_ENABLED, true); setSettingValue(SettingEnum.WEST_OPEN, blayout.getWest().isOpen()); setSettingValue(SettingEnum.WEST_COLLAPSIBLE, blayout.getWest().isCollapsible()); setSettingValue(SettingEnum.WEST_SPLITTABLE, blayout.getWest().isSplittable()); } else { setSettingValue(SettingEnum.WEST_ENABLED, false); } if (blayout.getCenter() != null) { setSettingValue(SettingEnum.CENTER_ENABLED, true); } else { setSettingValue(SettingEnum.CENTER_ENABLED, false); } } // --------------------- Interface Panel --------------------- @Override public void render() { super.render(); if (!hasNorth() && getSettingValue(SettingEnum.NORTH_ENABLED, false)) { setNorth(ContextUtil.getDefaultPanel(PlaceholderPanel.class)); getNorth().render(); } else if (hasNorth() && !getSettingValue(SettingEnum.NORTH_ENABLED, false)) { subpanels.remove(getNorth()); } if (!hasSouth() && getSettingValue(SettingEnum.SOUTH_ENABLED, false)) { setSouth(ContextUtil.getDefaultPanel(PlaceholderPanel.class)); getSouth().render(); } else if (hasSouth() && !getSettingValue(SettingEnum.SOUTH_ENABLED, false)) { subpanels.remove(getSouth()); } if (!hasWest() && getSettingValue(SettingEnum.WEST_ENABLED, false)) { setWest(ContextUtil.getDefaultPanel(PlaceholderPanel.class)); getWest().render(); } else if (hasWest() && !getSettingValue(SettingEnum.WEST_ENABLED, false)) { subpanels.remove(getWest()); } if (!hasEast() && getSettingValue(SettingEnum.EAST_ENABLED, false)) { setEast(ContextUtil.getDefaultPanel(PlaceholderPanel.class)); getEast().render(); } else if (hasEast() && !getSettingValue(SettingEnum.EAST_ENABLED, false)) { subpanels.remove(getEast()); } if (!hasCenter() && getSettingValue(SettingEnum.CENTER_ENABLED, false)) { setCenter(ContextUtil.getDefaultPanel(PlaceholderPanel.class)); getCenter().render(); } else if (hasCenter() && !getSettingValue(SettingEnum.CENTER_ENABLED, false)) { subpanels.remove(getCenter()); } if (blayout.getNorth() != null) { blayout.getNorth().setOpen(getSettingValue(SettingEnum.NORTH_OPEN, true)); blayout.getNorth().setCollapsible(getSettingValue(SettingEnum.NORTH_COLLAPSIBLE, true)); blayout.getNorth().setSplittable(getSettingValue(SettingEnum.NORTH_SPLITTABLE, true)); blayout.getNorth().setHeight(getSettingValue(SettingEnum.NORTH_HEIGHT, REGION_SIZE)); if (!blayout.getNorth().isOpen()) { blayout.getNorth().addEventListener(Events.ON_CLICK, selectHandler); } } if (blayout.getSouth() != null) { blayout.getSouth().setOpen(getSettingValue(SettingEnum.SOUTH_OPEN, true)); blayout.getSouth().setCollapsible(getSettingValue(SettingEnum.SOUTH_COLLAPSIBLE, true)); blayout.getSouth().setSplittable(getSettingValue(SettingEnum.SOUTH_SPLITTABLE, true)); blayout.getSouth().setHeight(getSettingValue(SettingEnum.SOUTH_HEIGHT, REGION_SIZE)); if (!blayout.getSouth().isOpen()) { blayout.getSouth().addEventListener(Events.ON_CLICK, selectHandler); } } if (blayout.getWest() != null) { blayout.getWest().setOpen(getSettingValue(SettingEnum.WEST_OPEN, true)); blayout.getWest().setCollapsible(getSettingValue(SettingEnum.WEST_COLLAPSIBLE, true)); blayout.getWest().setSplittable(getSettingValue(SettingEnum.WEST_SPLITTABLE, true)); blayout.getWest().setWidth(getSettingValue(SettingEnum.WEST_WIDTH, REGION_SIZE)); if (!blayout.getWest().isOpen()) { blayout.getWest().addEventListener(Events.ON_CLICK, selectHandler); } } if (blayout.getEast() != null) { blayout.getEast().setOpen(getSettingValue(SettingEnum.EAST_OPEN, true)); blayout.getEast().setCollapsible(getSettingValue(SettingEnum.EAST_COLLAPSIBLE, true)); blayout.getEast().setSplittable(getSettingValue(SettingEnum.EAST_SPLITTABLE, true)); blayout.getEast().setWidth(getSettingValue(SettingEnum.EAST_WIDTH, REGION_SIZE)); if (!blayout.getEast().isOpen()) { blayout.getEast().addEventListener(Events.ON_CLICK, selectHandler); } } mergeCommands(); } // --------------------- Interface ParentCapable --------------------- @Override public boolean accepts(Panel panel) { String region; if (!panel.hasAttribute(Attributes.ATTRIB_REGION)) { region = findNextAvailableRegion(); } else { region = panel.getAttribute(Attributes.ATTRIB_REGION, findNextAvailableRegion()); } return region != null; } @Override public void setChildren(Collection<Panel> panels) { if (panels.size() != DEFAULT_CHILDREN_COUNT && !panels.isEmpty()) throw new IllegalArgumentException("panel list should be either empty or have exactly 5 items (Center," + "" + "" + "North,South,West,East)"); int i = -1; for (Panel panel : panels) { i++; if (!PlaceholderPanel.class.isInstance(panel)) { panel.setAttribute(Attributes.ATTRIB_REGION, defaultRegionOrder[i]); subpanels.add(panel); } } } // -------------------------- OTHER METHODS -------------------------- @Override protected void afterRemove(Panel panel) { super.afterRemove(panel); String region = (String) panel.removeAttribute(Attributes.ATTRIB_REGION); if (region != null) { if (region.equals(Borderlayout.CENTER)) setSettingValue(SettingEnum.CENTER_ENABLED, false); else if (region.equals(Borderlayout.NORTH)) setSettingValue(SettingEnum.NORTH_ENABLED, false); else if (region.equals(Borderlayout.SOUTH)) setSettingValue(SettingEnum.SOUTH_ENABLED, false); else if (region.equals(Borderlayout.EAST)) setSettingValue(SettingEnum.EAST_ENABLED, false); else if (region.equals(Borderlayout.WEST)) setSettingValue(SettingEnum.WEST_ENABLED, false); } if (getCommandRenderer() != null) { if (panel instanceof CommandAware) { getCommandRenderer().removeCommandOwner((CommandAware) panel); getCommandRenderer().reset(); } } } @Override protected void afterAdd(Panel panel) { super.afterAdd(panel); if (getCommandRenderer() != null) { if (panel instanceof CommandAware) { getCommandRenderer().addCommandOwner((CommandAware) panel); getCommandRenderer().reset(); } } } @Override protected void beforeAdd(Panel panel) { super.beforeAdd(panel); if (!panel.hasAttribute(Attributes.ATTRIB_REGION)) { panel.setAttribute(Attributes.ATTRIB_REGION, findNextAvailableRegion()); } String name = panel.getAttribute(Attributes.ATTRIB_REGION).toString(); Panel oldPanel = getPanelByRegionName(name); if (oldPanel != null) { subpanels.remove(oldPanel); } LayoutRegion region = getNewRegionByName(name); panel.attach(region); region.setAttribute(Attributes.ATTRIB_PANEL, panel); } private String findNextAvailableRegion() { for (String region : defaultRegionOrder) { if (isRegionEnabled(region)) { if (getRegionByName(region) == null) return region; } } return null; } private boolean isRegionEnabled(String name) { if (name.equals(Borderlayout.CENTER)) return getSettingValue(SettingEnum.CENTER_ENABLED, false); else if (name.equals(Borderlayout.NORTH)) return getSettingValue(SettingEnum.NORTH_ENABLED, false); else if (name.equals(Borderlayout.SOUTH)) return getSettingValue(SettingEnum.SOUTH_ENABLED, false); else if (name.equals(Borderlayout.EAST)) return getSettingValue(SettingEnum.EAST_ENABLED, false); else if (name.equals(Borderlayout.WEST)) return getSettingValue(SettingEnum.WEST_ENABLED, false); return false; } private LayoutRegion getNewRegionByName(String name) { LayoutRegion region; if (name.equals(Borderlayout.CENTER)) { setSettingValue(SettingEnum.CENTER_ENABLED, true); region = new Center(); } else if (name.equals(Borderlayout.NORTH)) { setSettingValue(SettingEnum.NORTH_ENABLED, true); region = new North(); } else if (name.equals(Borderlayout.SOUTH)) { setSettingValue(SettingEnum.SOUTH_ENABLED, true); region = new South(); } else if (name.equals(Borderlayout.EAST)) { setSettingValue(SettingEnum.EAST_ENABLED, true); region = new East(); } else if (name.equals(Borderlayout.WEST)) { setSettingValue(SettingEnum.WEST_ENABLED, true); region = new West(); } else throw new IllegalStateException("region name is invalid: " + name); region.setParent(blayout); region.setBorder("none"); region.addEventListener(Events.ON_OPEN, new OpenEventHandler()); return region; } @Override protected void beforeRemove(Panel panel) { super.beforeRemove(panel); getRegionByName(panel.getAttribute(Attributes.ATTRIB_REGION).toString()).detach(); } @Override protected void beforeReplace(Panel oldItem, Panel newItem) { newItem.setAttribute(Attributes.ATTRIB_REGION, oldItem.getAttribute(Attributes.ATTRIB_REGION)); } protected Panel getCenter() { return getPanelByRegionName(Borderlayout.CENTER); } private Panel getPanelByRegionName(String name) { LayoutRegion region = getRegionByName(name); if (region == null) return null; else return (Panel) region.getAttribute(Attributes.ATTRIB_PANEL); } protected Panel getEast() { return getPanelByRegionName(Borderlayout.EAST); } protected Panel getNorth() { return getPanelByRegionName(Borderlayout.NORTH); } @Override protected Collection<Panel> getRenderedOrderOfChildren() { final List<Panel> subpanels = new ArrayList<Panel>(); for (String element : defaultRegionOrder) { final LayoutRegion region = getRegionByName(element); if (region != null) { subpanels.add((Panel) region.getAttribute(Attributes.ATTRIB_PANEL)); } else { subpanels.add(ContextUtil.getDefaultPanel(PlaceholderPanel.class)); } } return subpanels; } protected Panel getSouth() { return getPanelByRegionName(Borderlayout.SOUTH); } protected Panel getWest() { return getPanelByRegionName(Borderlayout.WEST); } protected boolean hasCenter() { return getRegionByName(Borderlayout.CENTER) != null; } protected boolean hasEast() { return getRegionByName(Borderlayout.EAST) != null; } protected boolean hasNorth() { return getRegionByName(Borderlayout.NORTH) != null; } protected boolean hasSouth() { return getRegionByName(Borderlayout.SOUTH) != null; } protected boolean hasWest() { return getRegionByName(Borderlayout.WEST) != null; } @Override protected boolean isActive(Panel panel) { LayoutRegion region = getRegionByPanel(panel); return region.isOpen(); } protected LayoutRegion getRegionByPanel(Panel panel) { if (subpanels.contains(panel) && panel.hasAttribute(Attributes.ATTRIB_REGION)) { return getRegionByName(panel.getAttribute(Attributes.ATTRIB_REGION).toString()); } return null; } private LayoutRegion getRegionByName(String name) { if (name == null || name.trim().length() == 0) throw new IllegalStateException("region name cannot be empty"); if (name.equals(Borderlayout.CENTER)) return blayout.getCenter(); else if (name.equals(Borderlayout.NORTH)) return blayout.getNorth(); else if (name.equals(Borderlayout.SOUTH)) return blayout.getSouth(); else if (name.equals(Borderlayout.EAST)) return blayout.getEast(); else if (name.equals(Borderlayout.WEST)) return blayout.getWest(); else throw new IllegalStateException("region name is invalid: " + name); } private int getIndexByName(String name) { if (name == null || name.trim().length() == 0) throw new IllegalStateException("region name cannot be empty"); if (name.equals(Borderlayout.CENTER)) return getSettingValue(SettingEnum.CENTER_CHILD_INDEX, 1); else if (name.equals(Borderlayout.NORTH)) return getSettingValue(SettingEnum.NORTH_CHILD_INDEX, 2); else if (name.equals(Borderlayout.SOUTH)) return getSettingValue(SettingEnum.SOUTH_CHILD_INDEX, 3); else if (name.equals(Borderlayout.EAST)) return getSettingValue(SettingEnum.EAST_CHILD_INDEX, 4); else if (name.equals(Borderlayout.WEST)) return getSettingValue(SettingEnum.WEST_CHILD_INDEX, 5); else throw new IllegalStateException("region name is invalid: " + name); } @Override protected <T extends Serializable> void onSettingValueChanged(SettingEnum id, T oldValue, T newValue) { if (id.equals(SettingEnum.CENTER_CHILD_INDEX)) { if (hasCenter()) { getCenter().setIndex((Integer) newValue); } } else if (id.equals(SettingEnum.NORTH_CHILD_INDEX)) { if (hasNorth()) { getNorth().setIndex((Integer) newValue); } } else if (id.equals(SettingEnum.SOUTH_CHILD_INDEX)) { if (hasSouth()) { getSouth().setIndex((Integer) newValue); } } else if (id.equals(SettingEnum.EAST_CHILD_INDEX)) { if (hasEast()) { getEast().setIndex((Integer) newValue); } } else if (id.equals(SettingEnum.WEST_CHILD_INDEX)) { if (hasWest()) { getWest().setIndex((Integer) newValue); } } else { super.onSettingValueChanged(id, oldValue, newValue); } } @Override public void afterPropertiesSet() throws Exception { super.afterPropertiesSet(); for (Panel panel : subpanels) { panel.setIndex(getIndexByName(panel.getAttribute(Attributes.ATTRIB_REGION).toString())); } subpanels.sort(); } @Override public SortedSet<Command> getMergedCommands() { SortedSet<Command> mergedCommands = new TreeSet<Command>(super.getCommands()); if (getCommandRenderer() == null) { mergeCommands(); } for (CommandAware commandAware : getCommandRenderer().getCommandOwners()) { if (!getCommandRenderer().getPrimaryOwner().equals(commandAware)) { SortedSet<Command> commands; if (commandAware instanceof CommandMerger) { commands = ((CommandMerger) commandAware).getMergedCommands(); } else { commands = commandAware.getCommands(); } for (Command command : commands) { if (commandAware instanceof CommandMerger) { //hinto for ToolbarRenderer so that in multiple command mergers scenario //the last merger (panel) can be identified so that it can be correctly mapped //to the correct region and this region settings can be applied (eg NORTH_EXCLUDE_CRUD_COMMANDS) command.setArg(CommandMerger.ATTRIB_COMMAND_MERGER, commandAware); } mergedCommands.add(command); } } } return Collections.unmodifiableSortedSet(mergedCommands); } protected void mergeCommands() { if (getCommandRenderer() == null) { initCommandRenderer(); } getCommandRenderer().reset(); for (Panel panel : subpanels) { if (panel instanceof CommandAware) { if (shouldMergeCommands(panel)) { ((CommandAware) panel).supressCommands(true); getCommandRenderer().addCommandOwner((CommandAware) panel); } else { if (panel instanceof SettingAware) { ((CommandAware) panel).supressCommands( ((SettingAware) panel).getSettingValue(SettingEnum.SUPRESS_COMMANDS, false)); } else { ((CommandAware) panel).supressCommands(false); } getCommandRenderer().removeCommandOwner((CommandAware) panel); } panel.setAttribute(CommandRenderer.ATTRIB_SUPPRESS_CRUD_COMMANDS, shouldSuppressCrudCommands(panel)); panel.render(); } } getCommandRenderer().render(); } private boolean shouldMergeCommands(Panel panel) { if (panel instanceof PlaceholderPanel) { return false; } else if (panel.equals(getNorth())) { return getSettingValue(SettingEnum.NORTH_MERGE_COMMANDS, true); } else if (panel.equals(getSouth())) { return getSettingValue(SettingEnum.SOUTH_MERGE_COMMANDS, true); } else if (panel.equals(getCenter())) { return getSettingValue(SettingEnum.CENTER_MERGE_COMMANDS, true); } else if (panel.equals(getWest())) { return getSettingValue(SettingEnum.WEST_MERGE_COMMANDS, true); } else if (panel.equals(getEast())) { return getSettingValue(SettingEnum.EAST_MERGE_COMMANDS, true); } else { return false; } } private boolean shouldSuppressCrudCommands(Panel panel) { if (panel instanceof PlaceholderPanel) { return false; } else if (panel.equals(getNorth())) { return getSettingValue(SettingEnum.NORTH_EXCLUDE_CRUD_COMMANDS, true); } else if (panel.equals(getSouth())) { return getSettingValue(SettingEnum.SOUTH_EXCLUDE_CRUD_COMMANDS, true); } else if (panel.equals(getCenter())) { return getSettingValue(SettingEnum.CENTER_EXCLUDE_CRUD_COMMANDS, true); } else if (panel.equals(getWest())) { return getSettingValue(SettingEnum.WEST_EXCLUDE_CRUD_COMMANDS, true); } else if (panel.equals(getEast())) { return getSettingValue(SettingEnum.EAST_EXCLUDE_CRUD_COMMANDS, true); } else { return false; } } /* private Class<? extends Entity> getSovereignTargetType() { for (Panel panel : subpanels) { if (panel instanceof TargetType) { if (((TargetType) panel).hasTargetType()) { return ((TargetType) panel).getTargetType(); } } } return null; } */ @Override protected void registerSettings() { super.registerSettings(); registerSetting(SettingEnum.NORTH_ENABLED, true); registerSetting(SettingEnum.NORTH_OPEN, true); registerSetting(SettingEnum.NORTH_COLLAPSIBLE, true); registerSetting(SettingEnum.NORTH_SPLITTABLE, true); registerSetting(SettingEnum.NORTH_HEIGHT, REGION_SIZE); registerSetting(SettingEnum.NORTH_MERGE_COMMANDS, true); registerSetting(SettingEnum.NORTH_EXCLUDE_CRUD_COMMANDS, false); registerSetting(SettingEnum.NORTH_CHILD_INDEX, 1); registerSetting(SettingEnum.SOUTH_ENABLED, true); registerSetting(SettingEnum.SOUTH_OPEN, true); registerSetting(SettingEnum.SOUTH_COLLAPSIBLE, true); registerSetting(SettingEnum.SOUTH_SPLITTABLE, true); registerSetting(SettingEnum.SOUTH_HEIGHT, REGION_SIZE); registerSetting(SettingEnum.SOUTH_MERGE_COMMANDS, true); registerSetting(SettingEnum.SOUTH_EXCLUDE_CRUD_COMMANDS, false); registerSetting(SettingEnum.SOUTH_CHILD_INDEX, 5); registerSetting(SettingEnum.WEST_ENABLED, true); registerSetting(SettingEnum.WEST_OPEN, true); registerSetting(SettingEnum.WEST_COLLAPSIBLE, true); registerSetting(SettingEnum.WEST_SPLITTABLE, true); registerSetting(SettingEnum.WEST_WIDTH, REGION_SIZE); registerSetting(SettingEnum.WEST_MERGE_COMMANDS, true); registerSetting(SettingEnum.WEST_EXCLUDE_CRUD_COMMANDS, false); registerSetting(SettingEnum.WEST_CHILD_INDEX, 2); registerSetting(SettingEnum.EAST_ENABLED, true); registerSetting(SettingEnum.EAST_OPEN, true); registerSetting(SettingEnum.EAST_COLLAPSIBLE, true); registerSetting(SettingEnum.EAST_SPLITTABLE, true); registerSetting(SettingEnum.EAST_WIDTH, REGION_SIZE); registerSetting(SettingEnum.EAST_MERGE_COMMANDS, true); registerSetting(SettingEnum.EAST_EXCLUDE_CRUD_COMMANDS, false); registerSetting(SettingEnum.EAST_CHILD_INDEX, 4); registerSetting(SettingEnum.CENTER_ENABLED, true); registerSetting(SettingEnum.CENTER_MERGE_COMMANDS, true); registerSetting(SettingEnum.CENTER_EXCLUDE_CRUD_COMMANDS, false); registerSetting(SettingEnum.CENTER_CHILD_INDEX, 3); } protected boolean setCenter(Panel panel) { panel.setAttribute(Attributes.ATTRIB_REGION, Borderlayout.CENTER); return subpanels.add(panel); } protected boolean setEast(Panel panel) { panel.setAttribute(Attributes.ATTRIB_REGION, Borderlayout.EAST); return subpanels.add(panel); } protected boolean setNorth(Panel panel) { panel.setAttribute(Attributes.ATTRIB_REGION, Borderlayout.NORTH); return subpanels.add(panel); } protected boolean setSouth(Panel panel) { panel.setAttribute(Attributes.ATTRIB_REGION, Borderlayout.SOUTH); return subpanels.add(panel); } protected boolean setWest(Panel panel) { panel.setAttribute(Attributes.ATTRIB_REGION, Borderlayout.WEST); return subpanels.add(panel); } private class OpenEventHandler implements EventListener<OpenEvent> { @Override public void onEvent(OpenEvent event) throws Exception { if (event.isOpen()) { Panel panel = (Panel) event.getTarget().getAttribute(Attributes.ATTRIB_PANEL); flushCache(panel); event.getTarget().removeEventListener(Events.ON_CLICK, selectHandler); } else { event.getTarget().addEventListener(Events.ON_CLICK, selectHandler); } } } private class SelectEventHandler implements EventListener<Event> { @Override public void onEvent(Event event) throws Exception { Panel panel = (Panel) event.getTarget().getAttribute(Attributes.ATTRIB_PANEL); flushCache(panel); } } @Override public Set<CommandAware> getMergedOwners() { Set<CommandAware> owners = new HashSet<CommandAware>(); for (Panel panel : subpanels) { if (panel instanceof CommandAware && shouldMergeCommands(panel)) { owners.add((CommandAware) panel); } } return owners; } @Override public String toString() { if (!subpanels.isEmpty() && subpanels.first() instanceof BindCapable && ((BindCapable) subpanels.first()).hasTargetEntity()) { return super.toString() + ": " + ((BindCapable) subpanels.first()).getTargetEntity().toString(); } else if (!subpanels.isEmpty() && subpanels.first() instanceof ParentCapable) { String activeEntity = subpanels.first().toString(); if (StringUtils.hasText(activeEntity) && activeEntity.contains(":")) { return super.toString() + ": " + activeEntity.split(":")[1].trim(); } return super.toString(); } else { return super.toString(); } } }