blob: 1ce751ac19e8a81da6235f3e90035af332463138 [file] [log] [blame]
/*
* Copyright (c) 1997, 1999, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.java.swing.plaf.motif;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JSplitPane;
import javax.swing.UIManager;
import javax.swing.plaf.basic.BasicSplitPaneUI;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
/**
* Divider used for Motif split pane.
* <p>
* <strong>Warning:</strong>
* Serialized objects of this class will not be compatible with
* future Swing releases. The current serialization support is appropriate
* for short term storage or RMI between applications running the same
* version of Swing. A future release of Swing will provide support for
* long term persistence.
*
* @author Jeff Dinkins
*/
public class MotifSplitPaneDivider extends BasicSplitPaneDivider
{
/**
* Default cursor, supers is package private, so we have to have one
* too.
*/
private static final Cursor defaultCursor =
Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
public static final int minimumThumbSize = 6;
public static final int defaultDividerSize = 18;
protected static final int pad = 6;
private int hThumbOffset = 30;
private int vThumbOffset = 40;
protected int hThumbWidth = 12;
protected int hThumbHeight = 18;
protected int vThumbWidth = 18;
protected int vThumbHeight = 12;
protected Color highlightColor;
protected Color shadowColor;
protected Color focusedColor;
/**
* Creates a new Motif SplitPaneDivider
*/
public MotifSplitPaneDivider(BasicSplitPaneUI ui) {
super(ui);
highlightColor = UIManager.getColor("SplitPane.highlight");
shadowColor = UIManager.getColor("SplitPane.shadow");
focusedColor = UIManager.getColor("SplitPane.activeThumb");
setDividerSize(hThumbWidth + pad);
}
/**
* overrides to hardcode the size of the divider
* PENDING(jeff) - rewrite JSplitPane so that this ins't needed
*/
public void setDividerSize(int newSize) {
Insets insets = getInsets();
int borderSize = 0;
if (getBasicSplitPaneUI().getOrientation() ==
JSplitPane.HORIZONTAL_SPLIT) {
if (insets != null) {
borderSize = insets.left + insets.right;
}
}
else if (insets != null) {
borderSize = insets.top + insets.bottom;
}
if (newSize < pad + minimumThumbSize + borderSize) {
setDividerSize(pad + minimumThumbSize + borderSize);
} else {
vThumbHeight = hThumbWidth = newSize - pad - borderSize;
super.setDividerSize(newSize);
}
}
/**
* Paints the divider.
*/
// PENDING(jeff) - the thumb's location and size is currently hard coded.
// It should be dynamic.
public void paint(Graphics g) {
Color bgColor = getBackground();
Dimension size = getSize();
// fill
g.setColor(getBackground());
g.fillRect(0, 0, size.width, size.height);
if(getBasicSplitPaneUI().getOrientation() ==
JSplitPane.HORIZONTAL_SPLIT) {
int center = size.width/2;
int x = center - hThumbWidth/2;
int y = hThumbOffset;
// split line
g.setColor(shadowColor);
g.drawLine(center-1, 0, center-1, size.height);
g.setColor(highlightColor);
g.drawLine(center, 0, center, size.height);
// draw thumb
g.setColor((splitPane.hasFocus()) ? focusedColor :
getBackground());
g.fillRect(x+1, y+1, hThumbWidth-2, hThumbHeight-1);
g.setColor(highlightColor);
g.drawLine(x, y, x+hThumbWidth-1, y); // top
g.drawLine(x, y+1, x, y+hThumbHeight-1); // left
g.setColor(shadowColor);
g.drawLine(x+1, y+hThumbHeight-1,
x+hThumbWidth-1, y+hThumbHeight-1); // bottom
g.drawLine(x+hThumbWidth-1, y+1,
x+hThumbWidth-1, y+hThumbHeight-2); // right
} else {
int center = size.height/2;
int x = size.width - vThumbOffset;
int y = size.height/2 - vThumbHeight/2;
// split line
g.setColor(shadowColor);
g.drawLine(0, center-1, size.width, center-1);
g.setColor(highlightColor);
g.drawLine(0, center, size.width, center);
// draw thumb
g.setColor((splitPane.hasFocus()) ? focusedColor :
getBackground());
g.fillRect(x+1, y+1, vThumbWidth-1, vThumbHeight-1);
g.setColor(highlightColor);
g.drawLine(x, y, x+vThumbWidth, y); // top
g.drawLine(x, y+1, x, y+vThumbHeight); // left
g.setColor(shadowColor);
g.drawLine(x+1, y+vThumbHeight,
x+vThumbWidth, y+vThumbHeight); // bottom
g.drawLine(x+vThumbWidth, y+1,
x+vThumbWidth, y+vThumbHeight-1); // right
}
super.paint(g);
}
/**
* The minimums size is the same as the preferredSize
*/
public Dimension getMinimumSize() {
return getPreferredSize();
}
/**
* Sets the SplitPaneUI that is using the receiver. This is completely
* overriden from super to create a different MouseHandler.
*/
public void setBasicSplitPaneUI(BasicSplitPaneUI newUI) {
if (splitPane != null) {
splitPane.removePropertyChangeListener(this);
if (mouseHandler != null) {
splitPane.removeMouseListener(mouseHandler);
splitPane.removeMouseMotionListener(mouseHandler);
removeMouseListener(mouseHandler);
removeMouseMotionListener(mouseHandler);
mouseHandler = null;
}
}
splitPaneUI = newUI;
if (newUI != null) {
splitPane = newUI.getSplitPane();
if (splitPane != null) {
if (mouseHandler == null) mouseHandler=new MotifMouseHandler();
splitPane.addMouseListener(mouseHandler);
splitPane.addMouseMotionListener(mouseHandler);
addMouseListener(mouseHandler);
addMouseMotionListener(mouseHandler);
splitPane.addPropertyChangeListener(this);
if (splitPane.isOneTouchExpandable()) {
oneTouchExpandableChanged();
}
}
}
else {
splitPane = null;
}
}
/**
* Returns true if the point at <code>x</code>, <code>y</code>
* is inside the thumb.
*/
private boolean isInThumb(int x, int y) {
Dimension size = getSize();
int thumbX;
int thumbY;
int thumbWidth;
int thumbHeight;
if (getBasicSplitPaneUI().getOrientation() ==
JSplitPane.HORIZONTAL_SPLIT) {
int center = size.width/2;
thumbX = center - hThumbWidth/2;
thumbY = hThumbOffset;
thumbWidth = hThumbWidth;
thumbHeight = hThumbHeight;
}
else {
int center = size.height/2;
thumbX = size.width - vThumbOffset;
thumbY = size.height/2 - vThumbHeight/2;
thumbWidth = vThumbWidth;
thumbHeight = vThumbHeight;
}
return (x >= thumbX && x < (thumbX + thumbWidth) &&
y >= thumbY && y < (thumbY + thumbHeight));
}
//
// Two methods are exposed so that MotifMouseHandler can see the
// superclass protected ivars
//
private DragController getDragger() {
return dragger;
}
private JSplitPane getSplitPane() {
return splitPane;
}
/**
* MouseHandler is subclassed to only pass off to super if the mouse
* is in the thumb. Motif only allows dragging when the thumb is clicked
* in.
*/
private class MotifMouseHandler extends MouseHandler {
public void mousePressed(MouseEvent e) {
// Constrain the mouse pressed to the thumb.
if (e.getSource() == MotifSplitPaneDivider.this &&
getDragger() == null && getSplitPane().isEnabled() &&
isInThumb(e.getX(), e.getY())) {
super.mousePressed(e);
}
}
public void mouseMoved(MouseEvent e) {
if (getDragger() != null) {
return;
}
if (!isInThumb(e.getX(), e.getY())) {
if (getCursor() != defaultCursor) {
setCursor(defaultCursor);
}
return;
}
super.mouseMoved(e);
}
}
}