001: /*
002: * WbTraversalPolicy.java
003: *
004: * This file is part of SQL Workbench/J, http://www.sql-workbench.net
005: *
006: * Copyright 2002-2008, Thomas Kellerer
007: * No part of this code maybe reused without the permission of the author
008: *
009: * To contact the author please send an email to: support@sql-workbench.net
010: *
011: */
012: package workbench.gui.components;
013:
014: import java.awt.Component;
015: import java.awt.Container;
016: import java.awt.FocusTraversalPolicy;
017: import java.util.ArrayList;
018: import java.util.Iterator;
019:
020: /**
021: *
022: * @author support@sql-workbench.net
023: */
024: public class WbTraversalPolicy extends FocusTraversalPolicy {
025: private ArrayList<Component> components = new ArrayList<Component>();
026: private Component defaultComponent = null;
027:
028: public WbTraversalPolicy() {
029: }
030:
031: public void setDefaultComponent(Component aComp) {
032: this .defaultComponent = aComp;
033: }
034:
035: public void addComponent(Component aComp) {
036: if (!this .components.contains(aComp)) {
037: this .components.add(aComp);
038: }
039: }
040:
041: private boolean checkAvailable() {
042: if (components.size() == 0)
043: return false;
044: Iterator<Component> itr = components.iterator();
045: while (itr.hasNext()) {
046: Component c = itr.next();
047: if (c.isEnabled())
048: return true;
049: }
050: return false;
051: }
052:
053: /**
054: * Returns the Component that should receive the focus after aComponent.
055: * focusCycleRoot must be a focus cycle root of aComponent.
056: *
057: * @param focusCycleRoot a focus cycle root of aComponent
058: * @param aComponent a (possibly indirect) child of focusCycleRoot, or
059: * focusCycleRoot itself
060: * @return the Component that should receive the focus after aComponent, or
061: * null if no suitable Component can be found
062: * @throws IllegalArgumentException if focusCycleRoot is not a focus cycle
063: * root of aComponent, or if either focusCycleRoot or aComponent is
064: * null
065: *
066: */
067: public Component getComponentAfter(Container focusCycleRoot,
068: Component aComponent) {
069: // Make sure we have at least one enabled component
070: // otherwise the recursion would never terminate!
071: if (!checkAvailable())
072: return null;
073:
074: int index = this .components.indexOf(aComponent);
075: Component result = null;
076: if (index < 0 || index == this .components.size() - 1)
077: result = this .components.get(0);
078: else
079: result = this .components.get(index + 1);
080: if (result.isEnabled()) {
081: return result;
082: }
083: return getComponentAfter(focusCycleRoot, result);
084: }
085:
086: /**
087: * Returns the Component that should receive the focus before aComponent.
088: * focusCycleRoot must be a focus cycle root of aComponent.
089: *
090: * @param focusCycleRoot a focus cycle root of aComponent
091: * @param aComponent a (possibly indirect) child of focusCycleRoot, or
092: * focusCycleRoot itself
093: * @return the Component that should receive the focus before aComponent,
094: * or null if no suitable Component can be found
095: * @throws IllegalArgumentException if focusCycleRoot is not a focus cycle
096: * root of aComponent, or if either focusCycleRoot or aComponent is
097: * null
098: *
099: */
100: public Component getComponentBefore(Container focusCycleRoot,
101: Component aComponent) {
102: // Make sure we have at least one enabled component
103: // otherwise the recursion would never terminate!
104: if (!checkAvailable())
105: return null;
106:
107: int index = this .components.indexOf(aComponent);
108:
109: Component result = null;
110: if (index <= 0)
111: result = this .components.get(this .components.size() - 1);
112: else
113: result = this .components.get(index - 1);
114:
115: if (result.isEnabled()) {
116: return result;
117: }
118: return getComponentBefore(focusCycleRoot, result);
119: }
120:
121: /** Returns the default Component to focus. This Component will be the first
122: * to receive focus when traversing down into a new focus traversal cycle
123: * rooted at focusCycleRoot.
124: *
125: * @param focusCycleRoot the focus cycle root whose default Component is to
126: * be returned
127: * @return the default Component in the traversal cycle when focusCycleRoot
128: * is the focus cycle root, or null if no suitable Component can
129: * be found
130: * @throws IllegalArgumentException if focusCycleRoot is null
131: *
132: */
133: public Component getDefaultComponent(Container focusCycleRoot) {
134: if (this .defaultComponent != null)
135: return this .defaultComponent;
136: if (this .components.size() > 0)
137: return this .components.get(0);
138: else
139: return null;
140: }
141:
142: /** Returns the first Component in the traversal cycle. This method is used
143: * to determine the next Component to focus when traversal wraps in the
144: * forward direction.
145: *
146: * @param focusCycleRoot the focus cycle root whose first Component is to
147: * be returned
148: * @return the first Component in the traversal cycle when focusCycleRoot
149: * is the focus cycle root, or null if no suitable Component can be
150: * found
151: * @throws IllegalArgumentException if focusCycleRoot is null
152: *
153: */
154: public Component getFirstComponent(Container focusCycleRoot) {
155: if (this .components.size() > 0)
156: return this .components.get(0);
157: else
158: return null;
159: }
160:
161: /** Returns the last Component in the traversal cycle. This method is used
162: * to determine the next Component to focus when traversal wraps in the
163: * reverse direction.
164: *
165: * @param focusCycleRoot the focus cycle root whose last Component is to be
166: * returned
167: * @return the last Component in the traversal cycle when focusCycleRoot is
168: * the focus cycle root, or null if no suitable Component can be
169: * found
170: * @throws IllegalArgumentException if focusCycleRoot is null
171: *
172: */
173: public Component getLastComponent(Container focusCycleRoot) {
174: if (this .components.size() > 0)
175: return this .components.get(this .components.size() - 1);
176: else
177: return null;
178: }
179:
180: }
|