/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common
* Development and Distribution License("CDDL") (collectively, the
* "License"). You may not use this file except in compliance with the
* License. You can obtain a copy of the License at
* http://www.netbeans.org/cddl-gplv2.html
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
* specific language governing permissions and limitations under the
* License. When distributing the software, include this License Header
* Notice in each file and include the License file at
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the
* License Header, with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Contributor(s):
*
* The Original Software is NetBeans. The Initial Developer of the Original
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
* Microsystems, Inc. All Rights Reserved.
*
* If you wish your version of this file to be governed by only the CDDL
* or only the GPL Version 2, indicate your decision by adding
* "[Contributor] elects to include this software in this distribution
* under the [CDDL or GPL Version 2] license." If you do not indicate a
* single choice of license, a recipient has the option to distribute
* your version of this file under either the CDDL, the GPL Version 2 or
* to extend the choice of license to its licensees as provided above.
* However, if you add GPL Version 2 code and therefore, elected the GPL
* Version 2 license, then the option applies only if the new code is
* made subject to such option by the copyright holder.
*/
/*
* TapPanel.java
*
* Created on 22. srpen 2003, 22:20
*/
package org.matveev.pomodoro4nb.controls.netbeans;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.lang.ref.*;
/**
* Panel that can collapse to a small size and be reexpanded.
*
* @author Tim Boudreau
*/
public final class TapPanel extends javax.swing.JPanel {
public static final int UP = 0;
public static final int DOWN = 2;
public static final String PROP_ORIENTATION = "orientation"; //NOI18N
private int orientation = UP;
private boolean armed = false;
private static boolean expanded = true;
private int minimumHeight = 8;
/**
* Creates a new instance of TapPanel
*/
public TapPanel() {
setLayout(new TrivialLayout());
}
private static WeakReference<Adap> adapRef = null;
static class Adap extends MouseAdapter implements
MouseMotionListener {
MouseListener other = null;
public void mouseEntered(MouseEvent e) {
((TapPanel) e.getSource()).setArmed(true);
}
public void mouseExited(MouseEvent e) {
((TapPanel) e.getSource()).setArmed(false);
}
public void mouseMoved(MouseEvent e) {
((TapPanel) e.getSource()).setArmed(((TapPanel) e.getSource()).isArmPoint(e.getPoint()));
}
public void mousePressed(MouseEvent e) {
if (((TapPanel) e.getSource()).isArmPoint(e.getPoint())) {
((TapPanel) e.getSource()).setExpanded(!((TapPanel) e.getSource()).isExpanded());
e.consume();
} else if (other != null) {
other.mousePressed(e);
}
}
public void mouseDragged(MouseEvent e) {
//do nothing
}
}
private static Adap getAdapter() {
Adap result = null;
if (adapRef != null) {
result = (Adap) adapRef.get();
}
if (result == null) {
result = new Adap();
adapRef = new WeakReference<Adap>(result);
}
return result;
}
/**
* Allows mouse clicks *not* in the expansion bar to cause the navigator component to become activated, but the user
* can click to expand/collapse without activating the component.
*/
void setSecondaryMouseHandler(MouseListener lis) {
getAdapter().other = lis;
}
public void addNotify() {
addMouseMotionListener(getAdapter());
addMouseListener(getAdapter());
super.addNotify();
}
public void removeNotify() {
super.removeNotify();
removeMouseMotionListener(getAdapter());
removeMouseListener(getAdapter());
}
public int getOrientation() {
return orientation;
}
public void setOrientation(int i) {
if (i != orientation) {
int oldOr = i;
orientation = i;
firePropertyChange(PROP_ORIENTATION, oldOr, i);
}
}
private void setArmed(boolean val) {
if (val != armed) {
armed = val;
repaint();
}
}
public boolean isExpanded() {
return expanded;
}
public Dimension getPreferredSize() {
return getLayout().preferredLayoutSize(this);
}
public Dimension getMinimumSize() {
Dimension d = getPreferredSize();
d.width = 20;
return d;
}
public Dimension getMaximumSize() {
return getPreferredSize();
}
public void setExpanded(boolean b) {
if (expanded != b) {
Dimension d = getPreferredSize();
expanded = b;
Dimension d1 = getPreferredSize();
if (isDisplayable()) {
revalidate();
}
}
}
private boolean isArmPoint(Point p) {
if (!expanded) {
return p.y > 0 && p.y < getHeight();
} else {
if (orientation == UP) {
return p.y > getHeight() - minimumHeight;
} else {
return p.y < minimumHeight;
}
}
}
public void updateBorder() {
if (orientation == UP) {
super.setBorder(BorderFactory.createEmptyBorder(0, 0,
minimumHeight, 0));
} else {
super.setBorder(BorderFactory.createEmptyBorder(
minimumHeight, 0, 0, 0));
}
}
public int getMinimumHeight() {
return minimumHeight;
}
public void setBorder() {
//do nothing
}
public void paintBorder(Graphics g) {
Color c = armed ? UIManager.getColor("List.selectionBackground") : getBackground(); //NOI18N
int x = 0;
int y = orientation == UP ? 1 + (getHeight() - minimumHeight)
: 0;
int w = getWidth();
int h = minimumHeight - 1;
g.setColor(c);
g.fillRect(x, y, w, h);
int pos = orientation == UP ? getHeight() - 1 : 0;
int dir = orientation == UP ? -1 : 1;
g.setColor(armed ? c.darker() : UIManager.getColor("controlShadow")); //NOI18N
g.drawLine(0, pos, w, pos);
pos += dir;
if ((orientation == UP) == expanded) {
up.paintIcon(this, g, (getWidth() / 2)
- (up.getIconWidth() / 2), getHeight()
- (minimumHeight + (expanded ? 0 : -1)));
} else {
down.paintIcon(this, g, (getWidth() / 2)
- (up.getIconWidth() / 2), expanded ? 2 : 1);
}
}
public void paintChildren(Graphics g) {
if (!expanded) {
return;
}
super.paintChildren(g);
}
private Icon up = new UpIcon();
private Icon down = new DownIcon();
private int ICON_SIZE = 8;
private class UpIcon implements Icon {
public int getIconHeight() {
return ICON_SIZE - 2;
}
public int getIconWidth() {
return ICON_SIZE + 2;
}
public void paintIcon(java.awt.Component c, Graphics g, int x,
int y) {
g.setColor(armed ? UIManager.getColor("List.selectionForeground") : //NOI18N
UIManager.getColor("controlShadow")); //NOI18N
/* int[] xPoints = new int[] {x+getIconWidth()/2, x+getIconWidth(), x};
int[] yPoints = new int[] {y, y+getIconHeight()-1, y+getIconHeight()-1};
*/
int[] xPoints = new int[]{x, x + 8, x + 4};
int[] yPoints = new int[]{y + 5, y + 5, y};
g.fillPolygon(xPoints, yPoints, 3);
}
}
private class DownIcon implements Icon {
public int getIconHeight() {
return ICON_SIZE - 3;
}
public int getIconWidth() {
return ICON_SIZE + 2;
}
public void paintIcon(java.awt.Component c, Graphics g, int x,
int y) {
x++;
g.setColor(armed ? UIManager.getColor("List.selectionForeground") : //NOI18N
UIManager.getColor("controlShadow")); //NOI18N
/*
int[] xPoints = new int[] {(x+getIconWidth()/2), x+getIconWidth()-1, x};
int[] yPoints = new int[] {y+getIconHeight()-2, y, y};
*/
int[] xPoints = new int[]{x, x + 8, x + 4};
int[] yPoints = new int[]{y, y, y + 4};
g.fillPolygon(xPoints, yPoints, 3);
}
}
}