📄 container.java
字号:
/*
* Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.lwuit;
import com.sun.lwuit.animations.Animation;
import com.sun.lwuit.animations.Transition;
import com.sun.lwuit.layouts.BorderLayout;
import com.sun.lwuit.layouts.FlowLayout;
import com.sun.lwuit.layouts.Layout;
import com.sun.lwuit.plaf.UIManager;
import java.util.Enumeration;
import com.sun.lwuit.geom.Dimension;
import com.sun.lwuit.geom.Rectangle;
import java.util.Vector;
/**
* A composite pattern with {@link Component}, allows nesting and arranging multiple
* components using a pluggable layout manager architecture. Containers can be nested
* one within the other to form elaborate UI's.
*
* @see com.sun.lwuit.layouts
* @see Component
* @author Chen Fishbein
*/
public class Container extends Component {
private Layout layout;
private java.util.Vector components = new java.util.Vector();
private boolean shouldLayout = true;
private boolean scrollableX;
private boolean scrollableY;
/**
* Constructs a new Container with a new layout manager.
*
* @param layout the specified layout manager
*/
public Container(Layout layout) {
super();
this.layout = layout;
setFocusable(false);
}
/**
* Constructs a new Container, with a {@link FlowLayout}.
*/
public Container() {
this(new FlowLayout());
}
/**
* Returns the layout manager responsible for arranging this container
*
* @return the container layout manager
*/
public Layout getLayout() {
return layout;
}
/**
* Sets the layout manager responsible for arranging this container
*
* @param layout the specified layout manager
*/
public void setLayout(Layout layout) {
this.layout = layout;
}
/**
* Same as setShouldCalcPreferredSize(true) but made accessible for
* layout managers
*/
public void invalidate() {
setShouldCalcPreferredSize(true);
}
/**
* @inheritDoc
*/
protected void setShouldCalcPreferredSize(boolean shouldCalcPreferredSize) {
super.setShouldCalcPreferredSize(shouldCalcPreferredSize);
shouldLayout = shouldCalcPreferredSize;
Enumeration enums = components.elements();
if (shouldLayout) {
while (enums.hasMoreElements()) {
Component cmp = (Component) enums.nextElement();
if (cmp instanceof Container) {
((Container) cmp).setShouldCalcPreferredSize(shouldCalcPreferredSize);
}
}
}
Form f = getComponentForm();
if (f != null) {
f.clearFocusVectors();
}
}
/**
* Returns the width for layout manager purposes, this takes scrolling
* into consideration unlike the getWidth method.
*
* @return the layout width
*/
public int getLayoutWidth() {
if (isScrollableX()) {
int scrollH = UIManager.getInstance().getLookAndFeel().getHorizontalScrollHeight();
return Math.max(getWidth() + scrollH, getPreferredW() + scrollH);
} else {
Container parent = getScrollableParent();
if (parent != null && parent.isScrollableX()) {
return Math.max(getWidth(), getPreferredW());
}
int width = getWidth();
if (width <= 0) {
return getPreferredW();
}
return width;
}
}
/**
* Returns the height for layout manager purposes, this takes scrolling
* into consideration unlike the getWidth method.
*
* @return the layout height
*/
public int getLayoutHeight() {
if (isScrollableY()) {
int scrollW = UIManager.getInstance().getLookAndFeel().getVerticalScrollWidth();
return Math.max(getHeight() + scrollW, getPreferredH() + scrollW);
} else {
Container parent = getScrollableParent();
if (parent != null && parent.isScrollableY()) {
return Math.max(getHeight(), getPreferredH());
}
int height = getHeight();
if (height <= 1) {
return getPreferredH();
}
return height;
}
}
/**
* Returns a parent container that is scrollable or null if no parent is
* scrollable.
*
* @return a parent container that is scrollable or null if no parent is
* scrollable.
*/
private Container getScrollableParent() {
Container parent = getParent();
while (parent != null) {
if (parent.isScrollable()) {
return parent;
}
parent = parent.getParent();
}
return null;
}
/**
* Adds a Component to the Container
*
* @param cmp the component to be added
*/
public void addComponent(Component cmp) {
// helper check for a common mistake...
if (layout instanceof BorderLayout) {
throw new IllegalArgumentException("Cannot add component to BorderLayout Container without constraint parameter");
}
insertComponentAt(components.size(), cmp);
}
/**
* Adds a Component to the Container
*
* @param constraints this method is useful when the Layout requires a constraint
* such as the BorderLayout.
* In this case you need to specify an additional data when you add a Component,
* such as "CENTER", "NORTH"...
*
* @param cmp component to add
*/
public void addComponent(Object constraints, Component cmp) {
layout.addLayoutComponent(constraints, cmp, this);
insertComponentAt(components.size(), cmp);
}
private void insertComponentAt(int index, Component cmp) {
if (cmp.getParent() != null) {
throw new IllegalArgumentException("Component is already contained in Container: " + cmp.getParent());
}
if (cmp instanceof Form) {
throw new IllegalArgumentException("A form cannot be added to a container");
}
cmp.setParent(this);
components.insertElementAt(cmp, index);
setShouldCalcPreferredSize(true);
if (isInitialized()) {
cmp.initComponentImpl();
}
Form f = getComponentForm();
if (f != null) {
f.clearFocusVectors();
}
//repaint();
}
/**
* This method adds the Component at a specific index location in the Conatiner
* Components array.
*
* @param index location to insert the Component
* @param cmp the Component to add
* @throws ArrayIndexOutOfBoundsException if index is out of bounds
* @throws IllegalArgumentException if Component is already contained or
* the cmp is a Form Component
*/
public void addComponent(int index, Component cmp) {
insertComponentAt(index, cmp);
}
/**
* This method replaces the current Component with the next Component.
* Current Component must be contained in this Container.
* This method return immediately.
*
* @param current a Component to remove from the Container
* @param next a Component that replaces the current Component
* @param t a Transition between the add and removal of the Components
* a Transition can be null
*/
public void replace(final Component current, final Component next, final Transition t) {
if (!contains(current)) {
throw new IllegalArgumentException("Component " + current + " is not contained in this Container");
}
if (t == null) {
replace(current, next);
return;
}
next.setX(current.getX());
next.setY(current.getY());
next.setWidth(current.getWidth());
next.setHeight(current.getHeight());
next.setParent(this);
if (next instanceof Container) {
((Container) next).layoutContainer();
}
Animation anim = new Anim(this, current, next, t);
// block events as long as the transition is animating
Display.getInstance().blockEvents(true);
// register the transition animation
getComponentForm().registerAnimated(anim);
}
void replace(final Component current, final Component next) {
int index = components.indexOf(current);
boolean currentFocused = false;
if (current.getComponentForm() != null && current.getComponentForm().getFocused() == current) {
currentFocused = true;
}
if (layout instanceof BorderLayout) {
Object constraint = layout.getComponentConstraint(current);
removeComponent(current);
layout.addLayoutComponent(constraint, next, Container.this);
} else {
removeComponent(current);
}
next.setParent(null);
if (index < 0) {
index = 0;
}
insertComponentAt(index, next);
if (currentFocused && next.isFocusable()) {
next.requestFocus();
}
}
/**
* @inheritDoc
*/
void initComponentImpl() {
if (!isInitialized()) {
if (isSmoothScrolling()) {
getComponentForm().registerAnimated(this);
}
super.initComponentImpl();
}
Enumeration e = components.elements();
while (e.hasMoreElements()) {
((Component) e.nextElement()).initComponentImpl();
}
}
/**
* removes a Component from the Container
*
* @param cmp the removed component
*/
public void removeComponent(Component cmp) {
Form parentForm = cmp.getComponentForm();
layout.removeLayoutComponent(cmp);
cmp.deinitializeImpl();
components.removeElement(cmp);
cmp.setParent(null);
cmp.setShouldCalcPreferredSize(true);
if (parentForm != null) {
if (parentForm.getFocused() == cmp || cmp instanceof Container && ((Container) cmp).contains(parentForm.getFocused())) {
parentForm.setFocused(null);
}
parentForm.clearFocusVectors();
if (cmp.isSmoothScrolling()) {
parentForm.deregisterAnimated(cmp);
}
}
setShouldCalcPreferredSize(true);
}
/**
* Cleansup the initialization flags in the hierachy
*/
void deinitializeImpl() {
super.deinitializeImpl();
int size = components.size();
for (int iter = 0; iter < size; iter++) {
((Component) components.elementAt(iter)).deinitializeImpl();
}
}
/**
* remove all Components from container
*/
public void removeAll() {
Form parentForm = getComponentForm();
if (parentForm != null) {
Component focus = parentForm.getFocused();
if (focus != null && contains(focus)) {
parentForm.setFocused(null);
}
}
Object[] arr = new Object[components.size()];
components.copyInto(arr);
for (int i = 0; i < arr.length; i++) {
removeComponent((Component) arr[i]);
}
}
/**
* Re-layout the container, this is useful when we modify the container hierarchy and
* need to redo the layout
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -