123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540 |
- /*
- * Copyright 2011 Vaadin Ltd.
- *
- * 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 com.vaadin.ui;
-
- import java.io.Serializable;
- import java.lang.reflect.Method;
- import java.util.Iterator;
-
- import com.vaadin.event.ComponentEventListener;
- import com.vaadin.event.MouseEvents.ClickEvent;
- import com.vaadin.server.Sizeable;
- import com.vaadin.shared.EventId;
- import com.vaadin.shared.MouseEventDetails;
- import com.vaadin.shared.ui.splitpanel.AbstractSplitPanelRpc;
- import com.vaadin.shared.ui.splitpanel.AbstractSplitPanelState;
- import com.vaadin.shared.ui.splitpanel.AbstractSplitPanelState.SplitterState;
- import com.vaadin.util.ReflectTools;
-
- /**
- * AbstractSplitPanel.
- *
- * <code>AbstractSplitPanel</code> is base class for a component container that
- * can contain two components. The components are split by a divider element.
- *
- * @author Vaadin Ltd.
- * @since 6.5
- */
- public abstract class AbstractSplitPanel extends AbstractComponentContainer {
-
- // TODO use Unit in AbstractSplitPanelState and remove these
- private Unit posUnit;
- private Unit posMinUnit;
- private Unit posMaxUnit;
-
- private AbstractSplitPanelRpc rpc = new AbstractSplitPanelRpc() {
-
- @Override
- public void splitterClick(MouseEventDetails mouseDetails) {
- fireEvent(new SplitterClickEvent(AbstractSplitPanel.this,
- mouseDetails));
- }
-
- @Override
- public void setSplitterPosition(float position) {
- getSplitterState().position = position;
- }
- };
-
- public AbstractSplitPanel() {
- registerRpc(rpc);
- setSplitPosition(50, Unit.PERCENTAGE, false);
- setSplitPositionLimits(0, Unit.PERCENTAGE, 100, Unit.PERCENTAGE);
- }
-
- /**
- * Modifiable and Serializable Iterator for the components, used by
- * {@link AbstractSplitPanel#getComponentIterator()}.
- */
- private class ComponentIterator implements Iterator<Component>,
- Serializable {
-
- int i = 0;
-
- @Override
- public boolean hasNext() {
- if (i < getComponentCount()) {
- return true;
- }
- return false;
- }
-
- @Override
- public Component next() {
- if (!hasNext()) {
- return null;
- }
- i++;
- if (i == 1) {
- return (getFirstComponent() == null ? getSecondComponent()
- : getFirstComponent());
- } else if (i == 2) {
- return getSecondComponent();
- }
- return null;
- }
-
- @Override
- public void remove() {
- if (i == 1) {
- if (getFirstComponent() != null) {
- setFirstComponent(null);
- i = 0;
- } else {
- setSecondComponent(null);
- }
- } else if (i == 2) {
- setSecondComponent(null);
- }
- }
- }
-
- /**
- * Add a component into this container. The component is added to the right
- * or under the previous component.
- *
- * @param c
- * the component to be added.
- */
-
- @Override
- public void addComponent(Component c) {
- if (getFirstComponent() == null) {
- setFirstComponent(c);
- } else if (getSecondComponent() == null) {
- setSecondComponent(c);
- } else {
- throw new UnsupportedOperationException(
- "Split panel can contain only two components");
- }
- }
-
- /**
- * Sets the first component of this split panel. Depending on the direction
- * the first component is shown at the top or to the left.
- *
- * @param c
- * The component to use as first component
- */
- public void setFirstComponent(Component c) {
- if (getFirstComponent() == c) {
- // Nothing to do
- return;
- }
-
- if (getFirstComponent() != null) {
- // detach old
- removeComponent(getFirstComponent());
- }
- getState().firstChild = c;
- if (c != null) {
- super.addComponent(c);
- }
- }
-
- /**
- * Sets the second component of this split panel. Depending on the direction
- * the second component is shown at the bottom or to the left.
- *
- * @param c
- * The component to use as first component
- */
- public void setSecondComponent(Component c) {
- if (getSecondComponent() == c) {
- // Nothing to do
- return;
- }
-
- if (getSecondComponent() != null) {
- // detach old
- removeComponent(getSecondComponent());
- }
- getState().secondChild = c;
- if (c != null) {
- super.addComponent(c);
- }
- }
-
- /**
- * Gets the first component of this split panel. Depending on the direction
- * this is either the component shown at the top or to the left.
- *
- * @return the first component of this split panel
- */
- public Component getFirstComponent() {
- return (Component) getState().firstChild;
- }
-
- /**
- * Gets the second component of this split panel. Depending on the direction
- * this is either the component shown at the top or to the left.
- *
- * @return the second component of this split panel
- */
- public Component getSecondComponent() {
- return (Component) getState().secondChild;
- }
-
- /**
- * Removes the component from this container.
- *
- * @param c
- * the component to be removed.
- */
-
- @Override
- public void removeComponent(Component c) {
- super.removeComponent(c);
- if (c == getFirstComponent()) {
- getState().firstChild = null;
- } else if (c == getSecondComponent()) {
- getState().secondChild = null;
- }
- markAsDirty();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.ComponentContainer#getComponentIterator()
- */
-
- @Override
- public Iterator<Component> iterator() {
- return new ComponentIterator();
- }
-
- /**
- * Gets the number of contained components. Consistent with the iterator
- * returned by {@link #getComponentIterator()}.
- *
- * @return the number of contained components (zero, one or two)
- */
-
- @Override
- public int getComponentCount() {
- int count = 0;
- if (getFirstComponent() != null) {
- count++;
- }
- if (getSecondComponent() != null) {
- count++;
- }
- return count;
- }
-
- /* Documented in superclass */
-
- @Override
- public void replaceComponent(Component oldComponent, Component newComponent) {
- if (oldComponent == getFirstComponent()) {
- setFirstComponent(newComponent);
- } else if (oldComponent == getSecondComponent()) {
- setSecondComponent(newComponent);
- }
- markAsDirty();
- }
-
- /**
- * Moves the position of the splitter.
- *
- * @param pos
- * the new size of the first region in the unit that was last
- * used (default is percentage). Fractions are only allowed when
- * unit is percentage.
- */
- public void setSplitPosition(float pos) {
- setSplitPosition(pos, posUnit, false);
- }
-
- /**
- * Moves the position of the splitter.
- *
- * @param pos
- * the new size of the region in the unit that was last used
- * (default is percentage). Fractions are only allowed when unit
- * is percentage.
- *
- * @param reverse
- * if set to true the split splitter position is measured by the
- * second region else it is measured by the first region
- */
- public void setSplitPosition(float pos, boolean reverse) {
- setSplitPosition(pos, posUnit, reverse);
- }
-
- /**
- * Moves the position of the splitter with given position and unit.
- *
- * @param pos
- * the new size of the first region. Fractions are only allowed
- * when unit is percentage.
- * @param unit
- * the unit (from {@link Sizeable}) in which the size is given.
- */
- public void setSplitPosition(float pos, Unit unit) {
- setSplitPosition(pos, unit, false);
- }
-
- /**
- * Moves the position of the splitter with given position and unit.
- *
- * @param pos
- * the new size of the first region. Fractions are only allowed
- * when unit is percentage.
- * @param unit
- * the unit (from {@link Sizeable}) in which the size is given.
- * @param reverse
- * if set to true the split splitter position is measured by the
- * second region else it is measured by the first region
- *
- */
- public void setSplitPosition(float pos, Unit unit, boolean reverse) {
- if (unit != Unit.PERCENTAGE && unit != Unit.PIXELS) {
- throw new IllegalArgumentException(
- "Only percentage and pixel units are allowed");
- }
- if (unit != Unit.PERCENTAGE) {
- pos = Math.round(pos);
- }
- SplitterState splitterState = getSplitterState();
- splitterState.position = pos;
- splitterState.positionUnit = unit.getSymbol();
- splitterState.positionReversed = reverse;
- posUnit = unit;
- }
-
- /**
- * Returns the current position of the splitter, in
- * {@link #getSplitPositionUnit()} units.
- *
- * @return position of the splitter
- */
- public float getSplitPosition() {
- return getSplitterState().position;
- }
-
- /**
- * Returns the unit of position of the splitter
- *
- * @return unit of position of the splitter
- */
- public Unit getSplitPositionUnit() {
- return posUnit;
- }
-
- /**
- * Sets the minimum split position to the given position and unit. If the
- * split position is reversed, maximum and minimum are also reversed.
- *
- * @param pos
- * the minimum position of the split
- * @param unit
- * the unit (from {@link Sizeable}) in which the size is given.
- * Allowed units are UNITS_PERCENTAGE and UNITS_PIXELS
- */
- public void setMinSplitPosition(int pos, Unit unit) {
- setSplitPositionLimits(pos, unit, getSplitterState().maxPosition,
- posMaxUnit);
- }
-
- /**
- * Returns the current minimum position of the splitter, in
- * {@link #getMinSplitPositionUnit()} units.
- *
- * @return the minimum position of the splitter
- */
- public float getMinSplitPosition() {
- return getSplitterState().minPosition;
- }
-
- /**
- * Returns the unit of the minimum position of the splitter.
- *
- * @return the unit of the minimum position of the splitter
- */
- public Unit getMinSplitPositionUnit() {
- return posMinUnit;
- }
-
- /**
- * Sets the maximum split position to the given position and unit. If the
- * split position is reversed, maximum and minimum are also reversed.
- *
- * @param pos
- * the maximum position of the split
- * @param unit
- * the unit (from {@link Sizeable}) in which the size is given.
- * Allowed units are UNITS_PERCENTAGE and UNITS_PIXELS
- */
- public void setMaxSplitPosition(float pos, Unit unit) {
- setSplitPositionLimits(getSplitterState().minPosition, posMinUnit, pos,
- unit);
- }
-
- /**
- * Returns the current maximum position of the splitter, in
- * {@link #getMaxSplitPositionUnit()} units.
- *
- * @return the maximum position of the splitter
- */
- public float getMaxSplitPosition() {
- return getSplitterState().maxPosition;
- }
-
- /**
- * Returns the unit of the maximum position of the splitter
- *
- * @return the unit of the maximum position of the splitter
- */
- public Unit getMaxSplitPositionUnit() {
- return posMaxUnit;
- }
-
- /**
- * Sets the maximum and minimum position of the splitter. If the split
- * position is reversed, maximum and minimum are also reversed.
- *
- * @param minPos
- * the new minimum position
- * @param minPosUnit
- * the unit (from {@link Sizeable}) in which the minimum position
- * is given.
- * @param maxPos
- * the new maximum position
- * @param maxPosUnit
- * the unit (from {@link Sizeable}) in which the maximum position
- * is given.
- */
- private void setSplitPositionLimits(float minPos, Unit minPosUnit,
- float maxPos, Unit maxPosUnit) {
- if ((minPosUnit != Unit.PERCENTAGE && minPosUnit != Unit.PIXELS)
- || (maxPosUnit != Unit.PERCENTAGE && maxPosUnit != Unit.PIXELS)) {
- throw new IllegalArgumentException(
- "Only percentage and pixel units are allowed");
- }
-
- SplitterState state = getSplitterState();
-
- state.minPosition = minPos;
- state.minPositionUnit = minPosUnit.getSymbol();
- posMinUnit = minPosUnit;
-
- state.maxPosition = maxPos;
- state.maxPositionUnit = maxPosUnit.getSymbol();
- posMaxUnit = maxPosUnit;
- }
-
- /**
- * Lock the SplitPanels position, disabling the user from dragging the split
- * handle.
- *
- * @param locked
- * Set <code>true</code> if locked, <code>false</code> otherwise.
- */
- public void setLocked(boolean locked) {
- getSplitterState().locked = locked;
- }
-
- /**
- * Is the SplitPanel handle locked (user not allowed to change split
- * position by dragging).
- *
- * @return <code>true</code> if locked, <code>false</code> otherwise.
- */
- public boolean isLocked() {
- return getSplitterState().locked;
- }
-
- /**
- * <code>SplitterClickListener</code> interface for listening for
- * <code>SplitterClickEvent</code> fired by a <code>SplitPanel</code>.
- *
- * @see SplitterClickEvent
- * @since 6.2
- */
- public interface SplitterClickListener extends ComponentEventListener {
-
- public static final Method clickMethod = ReflectTools.findMethod(
- SplitterClickListener.class, "splitterClick",
- SplitterClickEvent.class);
-
- /**
- * SplitPanel splitter has been clicked
- *
- * @param event
- * SplitterClickEvent event.
- */
- public void splitterClick(SplitterClickEvent event);
- }
-
- public static class SplitterClickEvent extends ClickEvent {
-
- public SplitterClickEvent(Component source,
- MouseEventDetails mouseEventDetails) {
- super(source, mouseEventDetails);
- }
-
- }
-
- public void addSplitterClickListener(SplitterClickListener listener) {
- addListener(EventId.CLICK_EVENT_IDENTIFIER, SplitterClickEvent.class,
- listener, SplitterClickListener.clickMethod);
- }
-
- /**
- * @deprecated As of 7.0, replaced by
- * {@link #addSplitterClickListener(SplitterClickListener)}
- **/
- @Deprecated
- public void addListener(SplitterClickListener listener) {
- addSplitterClickListener(listener);
- }
-
- public void removeSplitterClickListener(SplitterClickListener listener) {
- removeListener(EventId.CLICK_EVENT_IDENTIFIER,
- SplitterClickEvent.class, listener);
- }
-
- /**
- * @deprecated As of 7.0, replaced by
- * {@link #removeSplitterClickListener(SplitterClickListener)}
- **/
- @Deprecated
- public void removeListener(SplitterClickListener listener) {
- removeSplitterClickListener(listener);
- }
-
- @Override
- protected AbstractSplitPanelState getState() {
- return (AbstractSplitPanelState) super.getState();
- }
-
- private SplitterState getSplitterState() {
- return getState().splitterState;
- }
- }
|