001: package abbot.tester;
002:
003: import java.awt.BorderLayout;
004: import java.awt.Component;
005: import java.awt.Container;
006: import java.awt.Dialog;
007: import java.awt.Frame;
008: import java.awt.Insets;
009: import java.awt.Point;
010: import java.awt.Window;
011: import java.lang.reflect.Field;
012: import javax.swing.JToolBar;
013: import javax.swing.SwingConstants;
014: import javax.swing.SwingUtilities;
015: import javax.swing.plaf.ToolBarUI;
016: import javax.swing.plaf.basic.BasicToolBarUI;
017: import abbot.Log;
018:
019: /**
020: * @author twall@users.sf.net
021: */
022: public class JToolBarTester extends JComponentTester {
023: /** @return whether the bar is currently floating. */
024: public boolean isFloating(JToolBar bar) {
025: ToolBarUI ui = bar.getUI();
026: if (ui instanceof BasicToolBarUI)
027: return ((BasicToolBarUI) ui).isFloating();
028: // Have to guess; probably ought to check for sibling components
029: Window w = SwingUtilities.getWindowAncestor(bar);
030: return !(w instanceof Frame)
031: && bar.getParent().getComponentCount() == 1;
032: }
033:
034: /** Drag the tool bar to the given location, causing it to float.
035: * @throws ActionFailedException if the toolbar is not floatable
036: */
037: public void actionFloat(Component c, int x, int y) {
038: JToolBar bar = (JToolBar) c;
039: if (!bar.isFloatable()) {
040: throw new ActionFailedException(
041: "The JToolBar is not floatable");
042: }
043: if (isFloating(bar)) {
044: throw new ActionFailedException(
045: "The JToolBar is already floating");
046: }
047: Window w = SwingUtilities.getWindowAncestor(c);
048: // NOTE: should x, y be the window coordinates or where the
049: // cursor moves when the jtoolbar is dropped?
050: JToolBarLocation loc = new JToolBarLocation();
051: actionDrag(c, loc);
052: actionDrop(w, x - w.getX(), y - w.getY());
053: if (!isFloating(bar))
054: throw new ActionFailedException("Bar not floated");
055: }
056:
057: /** Make the given {@link JToolBar} float. */
058: public void actionFloat(Component c) {
059: Window w = SwingUtilities.getWindowAncestor(c);
060: Point where = w.getLocation();
061: actionFloat(c, where.x, where.y);
062: }
063:
064: /** Drop the {@link JToolBar} to the requested constraint position,
065: * which must be one of the constants {@link BorderLayout#NORTH NORTH},
066: * {@link BorderLayout#EAST EAST}, {@link BorderLayout#SOUTH SOUTH},
067: * or {@link BorderLayout#WEST WEST}.
068: */
069: public void actionUnfloat(Component c, String constraint) {
070: if (!BorderLayout.NORTH.equals(constraint)
071: && !BorderLayout.EAST.equals(constraint)
072: && !BorderLayout.SOUTH.equals(constraint)
073: && !BorderLayout.WEST.equals(constraint)) {
074: throw new IllegalArgumentException("Invalid drop location");
075: }
076: JToolBar bar = (JToolBar) c;
077: Container dock = null;
078: Class cls = bar.getUI().getClass();
079: // try to fly less blind
080: if (bar.getUI() instanceof BasicToolBarUI) {
081: cls = BasicToolBarUI.class;
082: }
083: try {
084: Field f = cls.getDeclaredField("dockingSource");
085: f.setAccessible(true);
086: dock = (Container) f.get(bar.getUI());
087: } catch (Exception e) {
088: Log.warn(e);
089: }
090: if (dock == null) {
091: throw new ActionFailedException("Can't determine dock");
092: }
093: actionDrag(bar, new JToolBarLocation());
094: actionDrop(dock, new DockLocation(bar, constraint));
095: if (isFloating(bar))
096: throw new ActionFailedException(
097: "Failed to dock the tool bar (" + constraint + ")");
098: }
099:
100: /** The only interesting location is where you grab the JToolBar. */
101: private class JToolBarLocation extends ComponentLocation {
102: public Point getPoint(Component c) {
103: JToolBar bar = (JToolBar) c;
104: Insets insets = bar.getInsets();
105: int x, y;
106: if (Math.max(Math.max(Math.max(insets.left, insets.top),
107: insets.right), insets.bottom) == insets.left) {
108: x = insets.left / 2;
109: y = c.getHeight() / 2;
110: } else if (Math.max(Math.max(insets.top, insets.right),
111: insets.bottom) == insets.top) {
112: x = c.getWidth() / 2;
113: y = insets.top / 2;
114: } else if (Math.max(insets.right, insets.bottom) == insets.right) {
115: x = c.getWidth() - insets.right / 2;
116: y = c.getHeight() / 2;
117: } else {
118: x = c.getWidth() / 2;
119: y = c.getHeight() - insets.bottom / 2;
120: }
121: return new Point(x, y);
122: }
123: }
124:
125: private class DockLocation extends ComponentLocation {
126: private String constraint;
127: private JToolBar bar;
128:
129: public DockLocation(JToolBar bar, String constraint) {
130: if (!BorderLayout.NORTH.equals(constraint)
131: && !BorderLayout.EAST.equals(constraint)
132: && !BorderLayout.SOUTH.equals(constraint)
133: && !BorderLayout.WEST.equals(constraint)) {
134: throw new IllegalArgumentException(
135: "Invalid dock location");
136: }
137: this .constraint = constraint;
138: this .bar = bar;
139: }
140:
141: public Point getPoint(Component c) {
142: if (!(c instanceof Container)) {
143: throw new LocationUnavailableException(
144: "Dock is not a container");
145: }
146: Container dock = (Container) c;
147: int x, y;
148: Insets insets = dock.getInsets();
149: // BasicToolBarUI prioritizes location N/E/W/S by proximity
150: // to the respective border. Close to top border is N, even
151: // if close to the left or right border.
152: int offset = bar.getOrientation() == SwingConstants.HORIZONTAL ? bar
153: .getHeight()
154: : bar.getWidth();
155: if (BorderLayout.NORTH.equals(constraint)) {
156: x = dock.getWidth() / 2;
157: y = insets.top;
158: } else if (BorderLayout.EAST.equals(constraint)) {
159: x = dock.getWidth() - insets.right - 1;
160: y = dock.getHeight() / 2;
161: // Make sure we don't get mistaken for NORTH
162: if (y < insets.top + offset) {
163: y = insets.top + offset;
164: }
165: } else if (BorderLayout.WEST.equals(constraint)) {
166: x = insets.left;
167: y = dock.getHeight() / 2;
168: // Make sure we don't get mistaken for NORTH
169: if (y < insets.top + offset) {
170: y = insets.top + offset;
171: }
172: } else {
173: x = dock.getWidth() / 2;
174: y = dock.getHeight() - insets.bottom - 1;
175: // Make sure we don't get mistaken for EAST or WEST
176: if (x < insets.left + offset) {
177: x = insets.left + offset;
178: } else if (x > dock.getWidth() - insets.right - offset
179: - 1) {
180: x = dock.getWidth() - insets.right - offset - 1;
181: }
182: }
183: return new Point(x, y);
184: }
185: }
186:
187: /** Close a floating toolbar, making it go back to its
188: * original container in its last known location.
189: * @param c the JToolBar instance
190: */
191: public void actionUnfloat(Component c) {
192: Window w = SwingUtilities.getWindowAncestor(c);
193: close(w);
194: waitForIdle();
195: }
196: }
|