/*
* Copyright (C) 2004 NNL Technology AB
* Visit www.infonode.net for information about InfoNode(R)
* products and how to contact NNL Technology AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
// $Id: SimpleSplitPane.java,v 1.28 2005/12/04 13:46:04 jesper Exp $
package net.infonode.gui;
import net.infonode.gui.panel.BaseContainer;
import net.infonode.gui.panel.SimplePanel;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList;
/**
* @author $Author: jesper $
* @version $Revision: 1.28 $
*/
public class SimpleSplitPane extends BaseContainer {
private LayoutManager splitLayout = new LayoutManager() {
public void addLayoutComponent(String name, Component comp) {
}
public void layoutContainer(Container parent) {
if (leftComponent == null || !leftComponent.isVisible()) {
maximize(rightComponent);
}
else if (rightComponent == null || !rightComponent.isVisible()) {
maximize(leftComponent);
}
else {
float dividerLocation = fixDividerLocation(getDividerLocation());
int totalSize = getViewSize();
int leftSize = (int) (totalSize * dividerLocation);
int otherSize = getOtherSize();
int offsetX = getInsets().left;
int offsetY = getInsets().top;
Dimension d = createSize(leftSize, otherSize);
leftComponent.setBounds(offsetX, offsetY, (int) d.getWidth(), (int) d.getHeight());
Point p = createPoint(leftSize, 0);
d = createSize(dividerSize, otherSize);
dividerPanel.setBounds(p.x + offsetX, p.y + offsetY, (int) d.getWidth(), (int) d.getHeight());
p = createPoint(leftSize + dividerSize, 0);
d = createSize(totalSize - leftSize, otherSize);
rightComponent.setBounds(p.x + offsetX, p.y + offsetY, (int) d.getWidth(), (int) d.getHeight());
}
}
private void maximize(Component component) {
if (component != null && component.isVisible()) {
Insets i = getInsets();
Dimension d = getSize();
component.setBounds(i.left, i.top, d.width - i.left - i.right, d.height - i.top - i.bottom);
}
dividerPanel.setBounds(0, 0, 0, 0);
}
public Dimension minimumLayoutSize(Container parent) {
Dimension d = createSize((leftComponent == null ? 0 : getDimensionSize(leftComponent.getMinimumSize())) + dividerSize
+ (rightComponent == null ? 0 : getDimensionSize(rightComponent.getMinimumSize())), Math.max(
leftComponent == null ? 0 : getOtherSize(leftComponent.getMinimumSize()), rightComponent == null
?
0
:
getOtherSize(
rightComponent.getMinimumSize())));
return new Dimension(d.width + getInsets().left + getInsets().right,
d.height + getInsets().top + getInsets().bottom);
}
public Dimension preferredLayoutSize(Container parent) {
boolean lv = leftComponent != null && leftComponent.isVisible();
boolean rv = rightComponent != null && rightComponent.isVisible();
Dimension d = createSize(
(lv ? getDimensionSize(leftComponent.getPreferredSize()) : 0) + (lv && rv ? dividerSize : 0) + (rv ?
getDimensionSize(
rightComponent.getPreferredSize()) :
0),
Math.max(lv ? getOtherSize(leftComponent.getPreferredSize()) : 0,
rv ? getOtherSize(rightComponent.getPreferredSize()) : 0));
return new Dimension(d.width + getInsets().left + getInsets().right,
d.height + getInsets().top + getInsets().bottom);
}
public void removeLayoutComponent(Component comp) {
}
};
private Component leftComponent;
private Component rightComponent;
private SimplePanel dividerPanel = new SimplePanel();
private Component dragIndicator;
private boolean dividerDraggable = true;
private boolean continuousLayout = true;
private float dragLocation;
private boolean horizontal;
private float dividerLocation = 0.5F;
private int dividerSize = 6;
private ArrayList listeners = new ArrayList(0);
private Color dragIndicatorColor = Color.DARK_GRAY;
public SimpleSplitPane(boolean horizontal) {
this(horizontal, false);
}
public SimpleSplitPane(boolean horizontal, boolean heavyWeightDragIndicator) {
setLayout(splitLayout);
add(dividerPanel);
setHorizontal(horizontal);
setHeavyWeightDragIndicator(heavyWeightDragIndicator);
dividerPanel.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1) {// &&
// MouseEventCoalesceManager.getInstance().isPressedAllowed(e))
// {
CursorManager.setGlobalCursor(getRootPane(), dividerPanel.getCursor());
if (dividerDraggable && !continuousLayout) {
float location = (float) (getPos(dividerPanel.getLocation()) - getOffset() + getPos(e.getPoint())) / getViewSize();
setDragIndicator(location);
}
}
}
public void mouseReleased(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1) {// &&
// MouseEventCoalesceManager.getInstance().isReleasedAllowed(e))
// {
CursorManager.resetGlobalCursor(getRootPane());
if (dividerDraggable && !continuousLayout) {
dragIndicator.setVisible(false);
setDividerLocation(dragLocation);
}
}
}
});
dividerPanel.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
if (dividerDraggable && /* MouseEventCoalesceManager.getInstance().isDraggedAllowed(e) && */(e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) != 0) {
float location = (float) (getPos(dividerPanel.getLocation()) - getOffset() + getPos(e.getPoint())) / getViewSize();
if (continuousLayout)
setDividerLocation(location);
else
setDragIndicator(location);
}
}
});
}
public SimpleSplitPane(boolean horizontal, Component leftComponent, Component rightComponent) {
this(horizontal);
setLeftComponent(leftComponent);
setRightComponent(rightComponent);
}
public void addListener(SimpleSplitPaneListener listener) {
ArrayList newListeners = new ArrayList(listeners.size() + 1);
newListeners.addAll(listeners);
listeners = newListeners;
listeners.add(listener);
}
public JComponent getDividerPanel() {
return dividerPanel;
}
public boolean isDividerDraggable() {
return dividerDraggable;
}
public void setDividerDraggable(boolean dividerDraggable) {
this.dividerDraggable = dividerDraggable;
updateDividerCursor();
}
public void setHeavyWeightDragIndicator(boolean heavyWeight) {
initDragIndicatior(heavyWeight);
}
public Color getDragIndicatorColor() {
return dragIndicatorColor;
}
public void setDragIndicatorColor(Color dragIndicatorColor) {
this.dragIndicatorColor = dragIndicatorColor;
dragIndicator.setBackground(dragIndicatorColor);
}
private void setDragIndicator(float location) {
dragLocation = fixDividerLocation(location);
dragIndicator.setVisible(true);
Point p = createPoint((int) (getViewSize() * dragLocation), 0);
Dimension d = createSize(dividerSize, getOtherSize());
dragIndicator.setBounds((int) (p.getX() + getInsets().left),
(int) (p.getY() + getInsets().top),
(int) d.getWidth(),
(int) d.getHeight());
}
private void initDragIndicatior(boolean heavyWeight) {
if (dragIndicator != null)
remove(dragIndicator);
if (heavyWeight) {
dragIndicator = new Canvas();
}
else {
dragIndicator = new BaseContainer();
}
add(dragIndicator, 0);
dragIndicator.setBackground(dragIndicatorColor);
dragIndicator.setVisible(false);
}
private float fixDividerLocation(float location) {
int totalSize = getViewSize();
if (totalSize <= 0)
return 0.5F;
int leftSize = Math.max((int) (totalSize * location),
leftComponent == null || !leftComponent.isVisible() ?
0 : getDimensionSize(leftComponent.getMinimumSize()));
leftSize = Math.min(leftSize,
totalSize - (rightComponent == null || !rightComponent.isVisible() ?
0 : getDimensionSize(rightComponent.getMinimumSize())));
return (float) leftSize / totalSize;
}
public void setContinuousLayout(boolean value) {
continuousLayout = value;
}
public boolean isContinuousLayout() {
return continuousLayout;
}
public int getDividerSize() {
return dividerSize;
}
public void setDividerSize(int dividerSize) {
this.dividerSize = dividerSize;
revalidate();
}
private int getOffset() {
return horizontal ? getInsets().left : getInsets().top;
}
private int getOtherSize() {
return horizontal ?
getHeight() - getInsets().top - getInsets().bottom : getWidth() - getInsets().left - getInsets().right;
}
private int getViewSize() {
return getDimensionSize(getSize()) - dividerSize - (horizontal ?
getInsets().left + getInsets().right :
getInsets().top + getInsets().bottom);
}
private int getDimensionSize(Dimension d) {
return (int) (horizontal ? d.getWidth() : d.getHeight());
}
private int getOtherSize(Dimension d) {
return (int) (horizontal ? d.getHeight() : d.getWidth());
}
private int getPos(Point p) {
return (int) (horizontal ? p.getX() : p.getY());
}
private Dimension createSize(int size, int otherSize) {
return horizontal ? new Dimension(size, otherSize) : new Dimension(otherSize, size);
}
private Point createPoint(int pos, int otherPos) {
return horizontal ? new Point(pos, otherPos) : new Point(otherPos, pos);
}
public boolean isHorizontal() {
return horizontal;
}
public void setHorizontal(boolean horizontal) {
this.horizontal = horizontal;
updateDividerCursor();
revalidate();
}
public float getDividerLocation() {
return dividerLocation;
}
public void setDividerLocation(float dividerLocation) {
this.dividerLocation = dividerLocation;
revalidate();
for (int i = 0; i < listeners.size(); i++)
((SimpleSplitPaneListener) listeners.get(i)).dividerLocationChanged(this);
}
public Component getLeftComponent() {
return leftComponent;
}
public void setLeftComponent(Component leftComponent) {
if (this.leftComponent != null)
remove(this.leftComponent);
this.leftComponent = leftComponent;
if (leftComponent != null)
add(leftComponent);
revalidate();
}
public Component getRightComponent() {
return rightComponent;
}
public void setRightComponent(Component rightComponent) {
if (this.rightComponent != null)
remove(this.rightComponent);
this.rightComponent = rightComponent;
if (rightComponent != null)
add(rightComponent);
revalidate();
}
private void updateDividerCursor() {
dividerPanel.setCursor(
dividerDraggable ?
new Cursor(horizontal ? Cursor.W_RESIZE_CURSOR : Cursor.N_RESIZE_CURSOR) : Cursor.getDefaultCursor());
}
public void setComponents(Component leftComponent, Component rightComponent) {
setLeftComponent(leftComponent);
setRightComponent(rightComponent);
}
}
|