001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Sergey Burlak
019: * @version $Revision$
020: */package javax.swing.plaf.basic;
021:
022: import java.awt.Component;
023: import java.awt.Container;
024: import java.awt.KeyboardFocusManager;
025: import java.awt.event.ActionEvent;
026: import java.util.HashSet;
027: import java.util.Set;
028:
029: import javax.swing.AbstractAction;
030: import javax.swing.Action;
031: import javax.swing.JComponent;
032: import javax.swing.JSplitPane;
033: import javax.swing.KeyStroke;
034:
035: import org.apache.harmony.x.swing.Utilities;
036:
037: class BasicSplitPaneKeyboardActions {
038: private static Action newNegativeIncrementAction() {
039: return new AbstractAction() {
040: public void actionPerformed(final ActionEvent e) {
041: JSplitPane splitPane = (JSplitPane) e.getSource();
042: if (splitPane.isFocusOwner()) {
043: splitPane.setDividerLocation(splitPane
044: .getDividerLocation() - 1);
045: splitPane.revalidate();
046: }
047: }
048: };
049: }
050:
051: private static Action newPositiveIncrementAction() {
052: return new AbstractAction() {
053: public void actionPerformed(final ActionEvent e) {
054: JSplitPane splitPane = (JSplitPane) e.getSource();
055: if (splitPane.isFocusOwner()) {
056: splitPane.setDividerLocation(splitPane
057: .getDividerLocation() + 1);
058: splitPane.revalidate();
059: }
060: }
061: };
062: }
063:
064: private static Action newSelectMinAction() {
065: return new AbstractAction() {
066: public void actionPerformed(final ActionEvent e) {
067: JSplitPane splitPane = (JSplitPane) e.getSource();
068: if (splitPane.isFocusOwner()) {
069: int splitPaneSize = splitPane.getOrientation() == JSplitPane.HORIZONTAL_SPLIT ? splitPane
070: .getInsets().left
071: : splitPane.getInsets().top;
072: splitPane.setDividerLocation(splitPaneSize);
073: splitPane.revalidate();
074: }
075: }
076: };
077: }
078:
079: private static Action newSelectMaxAction() {
080: return new AbstractAction() {
081: public void actionPerformed(final ActionEvent e) {
082: JSplitPane splitPane = (JSplitPane) e.getSource();
083: if (splitPane.isFocusOwner()) {
084: int splitPaneSize = splitPane.getOrientation() == JSplitPane.HORIZONTAL_SPLIT ? splitPane
085: .getWidth()
086: - splitPane.getInsets().right
087: : splitPane.getHeight()
088: - splitPane.getInsets().bottom;
089: splitPane.setDividerLocation(splitPaneSize
090: - splitPane.getDividerSize());
091: splitPane.revalidate();
092: }
093: }
094: };
095: }
096:
097: private static Action newToggleFocusAction() {
098: return new AbstractAction() {
099: public void actionPerformed(final ActionEvent e) {
100: JSplitPane splitPane = (JSplitPane) e.getSource();
101: isFocusRequested = false;
102: if (splitPane.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
103: if (splitPane.getLeftComponent() instanceof Container
104: && isHierarchyFocused((Container) splitPane
105: .getLeftComponent())
106: || splitPane.getLeftComponent()
107: .isFocusOwner()) {
108:
109: requestFocusInHierarchy((Container) splitPane
110: .getRightComponent());
111: } else {
112: requestFocusInHierarchy((Container) splitPane
113: .getLeftComponent());
114: }
115: } else {
116: if (splitPane.getTopComponent() instanceof Container
117: && isHierarchyFocused((Container) splitPane
118: .getLeftComponent())
119: || splitPane.getTopComponent()
120: .isFocusOwner()) {
121:
122: requestFocusInHierarchy((Container) splitPane
123: .getBottomComponent());
124: } else {
125: requestFocusInHierarchy((Container) splitPane
126: .getTopComponent());
127: }
128: }
129: }
130: };
131: }
132:
133: private static boolean isHierarchyFocused(final Container root) {
134: if (root.isFocusOwner()) {
135: return root.isFocusOwner();
136: }
137:
138: for (int i = 0; i < root.getComponentCount(); i++) {
139: Component child = root.getComponent(i);
140: if (child instanceof Container) {
141: return isHierarchyFocused((Container) child);
142: } else {
143: return child.isFocusOwner();
144: }
145: }
146:
147: return false;
148: }
149:
150: private static boolean isFocusRequested;
151:
152: private static void requestFocusInHierarchy(final Container root) {
153: if (isFocusRequested) {
154: return;
155: }
156:
157: if (root.getComponentCount() == 0) {
158: root.requestFocus();
159: isFocusRequested = true;
160:
161: return;
162: }
163:
164: for (int i = 0; i < root.getComponentCount(); i++) {
165: Component child = root.getComponent(i);
166: if (!(child instanceof JComponent)) {
167: root.requestFocus();
168: isFocusRequested = true;
169:
170: return;
171: }
172: if (child instanceof Container) {
173: requestFocusInHierarchy((Container) child);
174: if (isFocusRequested) {
175: return;
176: }
177: }
178: }
179: }
180:
181: private static Action newStartResizeAction() {
182: return new AbstractAction() {
183: public void actionPerformed(final ActionEvent e) {
184: JSplitPane splitPane = (JSplitPane) e.getSource();
185: splitPane.requestFocus();
186: ((BasicSplitPaneUI) splitPane.getUI()).getDivider()
187: .repaint();
188: }
189: };
190: }
191:
192: private static Action newFocusOutForwardAction() {
193: return new AbstractAction() {
194: public void actionPerformed(final ActionEvent e) {
195: JSplitPane splitPane = (JSplitPane) e.getSource();
196: Container ancestor = splitPane
197: .getFocusCycleRootAncestor();
198: if (ancestor == null) {
199: return;
200: }
201: Component rightComponent = splitPane
202: .getComponentOrientation().isLeftToRight() ? splitPane
203: .getRightComponent()
204: : splitPane.getLeftComponent();
205: Component result = ancestor.getFocusTraversalPolicy()
206: .getComponentAfter(ancestor, rightComponent);
207: if (result == null) {
208: return;
209: }
210:
211: result.requestFocus();
212: }
213: };
214: }
215:
216: private static Action newFocusOutBackwardAction() {
217: return new AbstractAction() {
218: public void actionPerformed(final ActionEvent e) {
219: JSplitPane splitPane = (JSplitPane) e.getSource();
220: Container ancestor = splitPane
221: .getFocusCycleRootAncestor();
222: if (ancestor == null) {
223: return;
224: }
225: Component leftComponent = splitPane
226: .getComponentOrientation().isLeftToRight() ? splitPane
227: .getLeftComponent()
228: : splitPane.getRightComponent();
229: Component result = ancestor.getFocusTraversalPolicy()
230: .getComponentBefore(ancestor, leftComponent);
231: if (result == null) {
232: return;
233: }
234:
235: result.requestFocus();
236: }
237: };
238: }
239:
240: public static void installKeyboardActions(final JSplitPane splitPane) {
241: Set forwardSet = new HashSet();
242: forwardSet.add(KeyStroke.getKeyStroke("pressed TAB"));
243: splitPane
244: .setFocusTraversalKeys(
245: KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
246: forwardSet);
247:
248: Set backwardSet = new HashSet();
249: backwardSet.add(KeyStroke.getKeyStroke("shift pressed TAB"));
250: splitPane.setFocusTraversalKeys(
251: KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
252: backwardSet);
253:
254: Utilities.installKeyboardActions(splitPane,
255: JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
256: "SplitPane.ancestorInputMap", null);
257:
258: splitPane.getActionMap().put("negativeIncrement",
259: newNegativeIncrementAction());
260: splitPane.getActionMap().put("positiveIncrement",
261: newPositiveIncrementAction());
262: splitPane.getActionMap().put("selectMin", newSelectMinAction());
263: splitPane.getActionMap().put("selectMax", newSelectMaxAction());
264: splitPane.getActionMap().put("startResize",
265: newStartResizeAction());
266: splitPane.getActionMap().put("toggleFocus",
267: newToggleFocusAction());
268: splitPane.getActionMap().put("focusOutForward",
269: newFocusOutForwardAction());
270: splitPane.getActionMap().put("focusOutBackward",
271: newFocusOutBackwardAction());
272: }
273: }
|