001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Sergey Burlak
020: * @version $Revision$
021: */package javax.swing;
022:
023: import java.awt.Component;
024: import java.awt.Container;
025: import java.awt.Dimension;
026: import java.awt.LayoutManager;
027: import java.awt.Point;
028: import java.awt.Rectangle;
029: import java.io.Serializable;
030:
031: public class ViewportLayout implements LayoutManager, Serializable {
032: private final UpdateStrategy HORIZONTAL_STRATEGY = new UpdateStrategy() {
033: public void updatePosition(final Point position,
034: final int newPos) {
035: position.x = newPos;
036: }
037:
038: public void updateSize(final Dimension size, final int newSize) {
039: size.width = newSize;
040: }
041:
042: public int getViewPosition(final Point viewPosition) {
043: return viewPosition.x;
044: }
045:
046: public int getScrollableLength(final Scrollable view,
047: final int currentViewLength,
048: final int currentViewportLength) {
049: if (view.getScrollableTracksViewportWidth()
050: && currentViewportLength > 0) {
051: return currentViewportLength;
052: } else {
053: return currentViewLength;
054: }
055: }
056: };
057:
058: private final UpdateStrategy VERTICAL_STRATEGY = new UpdateStrategy() {
059: public void updatePosition(final Point position,
060: final int newPos) {
061: position.y = newPos;
062: }
063:
064: public void updateSize(final Dimension size, final int newSize) {
065: size.height = newSize;
066: }
067:
068: public int getViewPosition(final Point viewPosition) {
069: return viewPosition.y;
070: }
071:
072: public int getScrollableLength(final Scrollable view,
073: final int currentViewLength,
074: final int currentViewportLength) {
075: if (view.getScrollableTracksViewportHeight()
076: && currentViewportLength > 0) {
077: return currentViewportLength;
078: } else {
079: return currentViewLength;
080: }
081: }
082: };
083:
084: public Dimension preferredLayoutSize(final Container c) {
085: Component view = ((JViewport) c).getView();
086: if (view == null) {
087: return new Dimension(0, 0);
088: }
089:
090: if (view instanceof Scrollable) {
091: Scrollable scrView = (Scrollable) view;
092:
093: return scrView.getPreferredScrollableViewportSize();
094: }
095:
096: return new Dimension(view.getPreferredSize());
097: }
098:
099: public Dimension minimumLayoutSize(final Container c) {
100: return new Dimension(4, 4);
101: }
102:
103: public void addLayoutComponent(final String s, final Component c) {
104: }
105:
106: public void removeLayoutComponent(final Component c) {
107: }
108:
109: public void layoutContainer(final Container c) {
110: JViewport viewport = (JViewport) c;
111: Component view = viewport.getView();
112: if (view == null) {
113: return;
114: }
115:
116: Rectangle bounds = viewport.getBounds();
117: Dimension viewPrfSize = view.getPreferredSize();
118:
119: Point viewPos = viewport.getViewPosition();
120: Dimension viewSize = new Dimension();
121:
122: HORIZONTAL_STRATEGY.update(view, viewPos, viewSize,
123: bounds.width, viewPrfSize.width);
124: VERTICAL_STRATEGY.update(view, viewPos, viewSize,
125: bounds.height, viewPrfSize.height);
126: viewport.getView().setSize(viewSize);
127: viewport.scrollUnderway = true;
128: viewport.setViewPosition(viewPos);
129: viewport.scrollUnderway = false;
130: }
131:
132: private abstract class UpdateStrategy {
133: public void update(final Component view,
134: final Point resultPosition, final Dimension resultSize,
135: final int currentViewportLength,
136: final int currentViewLength) {
137: int newViewLength;
138: if (view instanceof Scrollable) {
139: newViewLength = getScrollableLength((Scrollable) view,
140: currentViewLength, currentViewportLength);
141: } else {
142: newViewLength = Math.max(currentViewportLength,
143: currentViewLength);
144: }
145: updateSize(resultSize, newViewLength);
146:
147: if (currentViewportLength >= currentViewLength) {
148: updatePosition(resultPosition, 0);
149: } else {
150: int currentViewPos = getViewPosition(resultPosition);
151: int diff = -currentViewPos + newViewLength
152: - currentViewportLength;
153: if (diff < 0) {
154: updatePosition(resultPosition, currentViewPos
155: + diff);
156: }
157: }
158: }
159:
160: public abstract void updatePosition(Point position, int newPos);
161:
162: public abstract void updateSize(Dimension size, int newSize);
163:
164: public abstract int getViewPosition(Point viewPosition);
165:
166: public abstract int getScrollableLength(Scrollable view,
167: int currentViewLength, int currentViewportLength);
168: }
169: }
|