All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.codename1.ui.InterFormContainer Maven / Gradle / Ivy

There is a newer version: 7.0.164
Show newest version
/*
 * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Codename One designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *  
 * This code 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 General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 * 
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 * 
 * Please contact Codename One through http://www.codenameone.com/ if you 
 * need additional information or have any questions.
 */
package com.codename1.ui;

import static com.codename1.ui.ComponentSelector.$;
import com.codename1.ui.ComponentSelector.Filter;
import com.codename1.ui.geom.Dimension;
import com.codename1.ui.layouts.BorderLayout;
import java.util.HashMap;
import java.util.Map;

/**
 * A container that allows you to use the same component on multiple forms.  This is most 
 * useful for adding a global footer or sidebar that appears on multiple forms, or even the 
 * whole app.  For example, the Twitter app has tabs for "Home", "Search", "Messages", etc.. that
 * are always shown in the app, and are fixed in place, even between forms.  This container
 * allows you to achieve a similar thing with Codename One apps.
 * 
 * 

Note that the InterFormContainer object itself cannot be added to multiple forms. You * need to create two InterFormContainer instances that share the same content.

* @since 7.0 * @author shannah */ public class InterFormContainer extends Container { private Component content; /** * Creates an interform container with the provided content. * @param content The component that is to be shared across multiple forms. */ public InterFormContainer(Component content) { this.content = content; setLayout(new BorderLayout()); $(this).selectAllStyles().setPadding(0).setMargin(0); } /** * {@inheritDoc} */ @Override protected void initComponent() { if (content.getParent() != this) { content.remove(); add(CENTER, content); } super.initComponent(); } /** * Finds any InterformContainer instances in the UI hierarchy rooted at {@literal root} * that contains the same content as this container. * @param root A component/container whose UI hierarchy is to be searched. * @return An InterFormContainer with the same content as this container, or null if none is found. */ public InterFormContainer findPeer(Component root) { if (root.getClass() == InterFormContainer.class) { InterFormContainer cnt = (InterFormContainer)root; if (cnt.content == content) { return cnt; } } if (root instanceof Container) { Container cnt = (Container)root; int len = cnt.getComponentCount(); for (int i=0; i findCommonContainers(Component root1, Component root2) { final Map set1 = new HashMap(); final Map set2 = new HashMap(); final Map out = new HashMap(); ComponentSelector.select("*", root1).filter(new Filter() { @Override public boolean filter(Component c) { if (c.getClass() == InterFormContainer.class) { set1.put(((InterFormContainer)c).content, (InterFormContainer)c); return true; } return false; } }); ComponentSelector.select("*", root2).filter(new Filter() { @Override public boolean filter(Component c) { if (c.getClass() == InterFormContainer.class) { set2.put(((InterFormContainer)c).content, (InterFormContainer)c); return true; } return false; } }); for (Component c : set1.keySet()) { if (set2.containsKey(c)) { out.put(set1.get(c), set2.get(c)); } } return out; } /** * {@inheritDoc} */ public void paint(Graphics g) { if (!isVisible()) { return; } if (content.getParent() != this) { if (isInitialized() && !content.isInitialized()) { if (content.getParent() != null) { content.remove(); } add(BorderLayout.CENTER, content); } } g.translate(getX() - content.getX(), getY() - content.getY()); content.paintComponentBackground(g); content.paint(g); g.translate(content.getX() - getX(), content.getY() - getY()); } /** * {@inheritDoc} */ @Override protected Dimension calcPreferredSize() { return new Dimension(content.getPreferredW() + content.getStyle().getHorizontalMargins(), content.getPreferredH() + content.getStyle().getVerticalMargins()); } /** * Injects the given "content" as an InterFormContainer inside the component hierarchy * rooted at "root" * @param selector A selector to identify the component to add the container to. See {@link ComponentSelector}. * @param root The root container serving as a starting point for the selector search. * @param content The content to inject. * @return The InterFormContainer that was injected, or null if the selector didn't match any containers. */ public static InterFormContainer inject(String selector, Container root, Component content) { for (Component c : $(selector, root)) { if (c instanceof Container) { Container slotCnt = (Container)c; if (!(slotCnt.getLayout() instanceof BorderLayout)) { slotCnt.setLayout(new BorderLayout()); } slotCnt.getStyle().stripMarginAndPadding(); slotCnt.removeAll(); InterFormContainer ifc = new InterFormContainer(content); slotCnt.add(BorderLayout.CENTER, ifc); return ifc; } } return null; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy