001 /*
002 * Created on Feb 2, 2008
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
005 * the License. You may obtain a copy of the License at
006 *
007 * http://www.apache.org/licenses/LICENSE-2.0
008 *
009 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
010 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
011 * specific language governing permissions and limitations under the License.
012 *
013 * Copyright @2008-2010 the original author or authors.
014 */
015 package org.fest.swing.driver;
016
017 import static java.awt.BorderLayout.*;
018 import static java.lang.Math.max;
019 import static javax.swing.SwingConstants.HORIZONTAL;
020 import static org.fest.util.Arrays.format;
021 import static org.fest.util.Strings.concat;
022 import static org.fest.util.Strings.quote;
023
024 import java.awt.*;
025
026 import javax.swing.JToolBar;
027
028 import org.fest.swing.annotation.RunsInCurrentThread;
029
030 /**
031 * Understands a visible location on a <code>{@link JToolBar}</code>.
032 *
033 * @author Yvonne Wang
034 * @author Alex Ruiz
035 */
036 public final class JToolBarLocation {
037
038 private static String[] VALID_CONSTRAINTS = { NORTH, EAST, SOUTH, WEST };
039
040 /**
041 * Returns the point where to grab the given <code>{@link JToolBar}</code>.
042 * <p>
043 * <b>Note:</b> This method is <b>not</b> guaranteed to be executed in the event dispatch thread (EDT.) Clients are
044 * responsible for calling this method from the EDT.
045 * </p>
046 * @param toolBar the target <code>JToolBar</code>.
047 * @return the point where to grab the given <code>JToolBar</code>.
048 */
049 @RunsInCurrentThread
050 public Point pointToGrab(JToolBar toolBar) {
051 Insets insets = toolBar.getInsets();
052 int width = toolBar.getWidth();
053 int height = toolBar.getHeight();
054 if (max(max(max(insets.left, insets.top), insets.right), insets.bottom) == insets.left)
055 return new Point(insets.left / 2, height / 2);
056 if (max(max(insets.top, insets.right), insets.bottom) == insets.top)
057 return new Point(width / 2, insets.top / 2);
058 if (max(insets.right, insets.bottom) == insets.right)
059 return new Point(width - insets.right / 2, height / 2);
060 return new Point(width / 2, height - insets.bottom / 2);
061 }
062
063 /**
064 * Returns the location where to dock the given <code>{@link JToolBar}</code>, at the given constraint position.
065 * The constraint position must be one of the constants <code>{@link BorderLayout#NORTH NORTH}</code>,
066 * <code>{@link BorderLayout#EAST EAST}</code>, <code>{@link BorderLayout#SOUTH SOUTH}</code>, or
067 * <code>{@link BorderLayout#WEST WEST}</code>.
068 * <p>
069 * <b>Note:</b> This method is <b>not</b> guaranteed to be executed in the event dispatch thread (EDT.) Clients are
070 * responsible for calling this method from the EDT.
071 * </p>
072 * @param toolBar the target <code>JToolBar</code>.
073 * @param dock the container where to dock the <code>JToolBar</code> to.
074 * @param constraint the constraint position.
075 * @return the location where to dock the given <code>JToolBar</code>.
076 * @throws IllegalArgumentException if the constraint has an invalid value.
077 */
078 @RunsInCurrentThread
079 public Point dockLocation(JToolBar toolBar, Container dock, String constraint) {
080 validate(constraint);
081 Insets insets = dock.getInsets();
082 // BasicToolBarUI prioritizes location N/E/W/S by proximity to the respective border. Close to top border is N, even
083 // if close to the left or right border.
084 int offset = isHorizontal(toolBar) ? toolBar.getHeight() : toolBar.getWidth();
085 Dimension dockSize = dock.getSize();
086 if (NORTH.equals(constraint))
087 return new Point(dockSize.width / 2, insets.top);
088 if (EAST.equals(constraint))
089 return new Point(dockSize.width - insets.right - 1, verticalDockingYCoordinate(dockSize.height, insets, offset));
090 if (WEST.equals(constraint))
091 return new Point(insets.left, verticalDockingYCoordinate(dockSize.height, insets, offset));
092 int x = dockSize.width / 2;
093 // Make sure we don't get mistaken for EAST or WEST
094 if (x < insets.left + offset)
095 x = insets.left + offset;
096 else if (x > dockSize.width - insets.right - offset - 1)
097 x = dockSize.width - insets.right - offset - 1;
098 return new Point(x, dockSize.height - insets.bottom - 1);
099 }
100
101 @RunsInCurrentThread
102 private boolean isHorizontal(JToolBar toolBar) {
103 return toolBar.getOrientation() == HORIZONTAL;
104 }
105
106 private void validate(String constraint) {
107 for (String validConstraint : VALID_CONSTRAINTS)
108 if (validConstraint.equals(constraint)) return;
109 throw invalidConstraint(constraint);
110 }
111
112 private IllegalArgumentException invalidConstraint(String constraint) {
113 throw new IllegalArgumentException(
114 concat(quote(constraint), " is not a valid constraint. Valid constraints are ", format(VALID_CONSTRAINTS)));
115 }
116
117 private int verticalDockingYCoordinate(int dockHeight, Insets insets, int offset) {
118 int y = dockHeight / 2;
119 // Make sure we don't get mistaken for NORTH
120 if (y < insets.top + offset) y = insets.top + offset;
121 return y;
122 }
123 }