blob: 5cc3fd4823d3e81c50ee0f4be0620e3e6480032c [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
/**
* @author Sergey Burlak
*/
package javax.swing;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.LayoutManager;
import java.awt.Point;
import java.awt.Rectangle;
import java.io.Serializable;
public class ViewportLayout implements LayoutManager, Serializable {
private final UpdateStrategy HORIZONTAL_STRATEGY = new UpdateStrategy() {
public void updatePosition(final Point position, final int newPos) {
position.x = newPos;
}
public void updateSize(final Dimension size, final int newSize) {
size.width = newSize;
}
public int getViewPosition(final Point viewPosition) {
return viewPosition.x;
}
public int getScrollableLength(final Scrollable view, final int currentViewLength, final int currentViewportLength) {
if (view.getScrollableTracksViewportWidth() && currentViewportLength > 0) {
return currentViewportLength;
} else {
return currentViewLength;
}
}
};
private final UpdateStrategy VERTICAL_STRATEGY = new UpdateStrategy() {
public void updatePosition(final Point position, final int newPos) {
position.y = newPos;
}
public void updateSize(final Dimension size, final int newSize) {
size.height = newSize;
}
public int getViewPosition(final Point viewPosition) {
return viewPosition.y;
}
public int getScrollableLength(final Scrollable view, final int currentViewLength, final int currentViewportLength) {
if (view.getScrollableTracksViewportHeight() && currentViewportLength > 0) {
return currentViewportLength;
} else {
return currentViewLength;
}
}
};
public Dimension preferredLayoutSize(final Container c) {
Component view = ((JViewport)c).getView();
if (view == null) {
return new Dimension(0, 0);
}
if (view instanceof Scrollable) {
Scrollable scrView = (Scrollable)view;
return scrView.getPreferredScrollableViewportSize();
}
return new Dimension(view.getPreferredSize());
}
public Dimension minimumLayoutSize(final Container c) {
return new Dimension(4, 4);
}
public void addLayoutComponent(final String s, final Component c) {
}
public void removeLayoutComponent(final Component c) {
}
public void layoutContainer(final Container c) {
JViewport viewport = (JViewport)c;
Component view = viewport.getView();
if (view == null) {
return;
}
Rectangle bounds = viewport.getBounds();
Dimension viewPrfSize = view.getPreferredSize();
Point viewPos = viewport.getViewPosition();
Dimension viewSize = new Dimension();
HORIZONTAL_STRATEGY.update(view, viewPos, viewSize, bounds.width, viewPrfSize.width);
VERTICAL_STRATEGY.update(view, viewPos, viewSize, bounds.height, viewPrfSize.height);
viewport.getView().setSize(viewSize);
viewport.scrollUnderway = true;
viewport.setViewPosition(viewPos);
viewport.scrollUnderway = false;
}
private abstract class UpdateStrategy {
public void update(final Component view, final Point resultPosition, final Dimension resultSize, final int currentViewportLength, final int currentViewLength) {
int newViewLength;
if (view instanceof Scrollable) {
newViewLength = getScrollableLength((Scrollable)view, currentViewLength, currentViewportLength);
} else {
newViewLength = Math.max(currentViewportLength, currentViewLength);
}
updateSize(resultSize, newViewLength);
if (currentViewportLength >= currentViewLength) {
updatePosition(resultPosition, 0);
} else {
int currentViewPos = getViewPosition(resultPosition);
int diff = -currentViewPos + newViewLength - currentViewportLength;
if (diff < 0) {
updatePosition(resultPosition, currentViewPos + diff);
}
}
}
public abstract void updatePosition(Point position, int newPos);
public abstract void updateSize(Dimension size, int newSize);
public abstract int getViewPosition(Point viewPosition);
public abstract int getScrollableLength(Scrollable view, int currentViewLength, int currentViewportLength);
}
}