/* * 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); } } }