1 /*
2 * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.javafx.scene.control.behavior;
27
28 import javafx.geometry.NodeOrientation;
29 import javafx.scene.control.ScrollPane;
30 import javafx.scene.input.KeyEvent;
31 import javafx.scene.input.MouseEvent;
32 import java.util.ArrayList;
33 import java.util.List;
34 import com.sun.javafx.scene.control.skin.ScrollPaneSkin;
35 import static javafx.scene.input.KeyCode.DOWN;
36 import static javafx.scene.input.KeyCode.F4;
37 import static javafx.scene.input.KeyCode.LEFT;
38 import static javafx.scene.input.KeyCode.PAGE_DOWN;
39 import static javafx.scene.input.KeyCode.PAGE_UP;
40 import static javafx.scene.input.KeyCode.RIGHT;
41 import static javafx.scene.input.KeyCode.SPACE;
42 import static javafx.scene.input.KeyCode.UP;
43 import static javafx.scene.input.KeyCode.HOME;
44 import static javafx.scene.input.KeyCode.END;
45
46
47 /**
48 * Behavior for ScrollPane.
49 *
50 * TODO: the function variables are a poor way to couple to the rest of
51 * the system. This technique avoids a direct dependency on the skin class.
52 * However, this should really be coupled through the control itself instead
53 * of directly to the skin.
54 */
55 public class ScrollPaneBehavior extends BehaviorBase<ScrollPane> {
56
57 /***************************************************************************
58 * *
59 * Constructors *
60 * *
61 **************************************************************************/
62
63 public ScrollPaneBehavior(ScrollPane scrollPane) {
64 super(scrollPane, SCROLL_PANE_BINDINGS);
65 }
66
67 /***************************************************************************
68 * *
69 * Functions *
70 * *
71 **************************************************************************/
72
73 public void horizontalUnitIncrement() {
74 ((ScrollPaneSkin)getControl().getSkin()).hsbIncrement();
75 }
76 public void horizontalUnitDecrement() {
77 ((ScrollPaneSkin)getControl().getSkin()).hsbDecrement();
78 }
79 public void verticalUnitIncrement() {
80 ((ScrollPaneSkin)getControl().getSkin()).vsbIncrement();
81 }
82 void verticalUnitDecrement() {
83 ((ScrollPaneSkin)getControl().getSkin()).vsbDecrement();
84 }
85 void horizontalPageIncrement() {
86 ((ScrollPaneSkin)getControl().getSkin()).hsbPageIncrement();
87 }
88 void horizontalPageDecrement() {
89 ((ScrollPaneSkin)getControl().getSkin()).hsbPageDecrement();
90 }
91 void verticalPageIncrement() {
92 ((ScrollPaneSkin)getControl().getSkin()).vsbPageIncrement();
93 }
94 void verticalPageDecrement() {
95 ((ScrollPaneSkin)getControl().getSkin()).vsbPageDecrement();
96 }
97 void verticalHome() {
98 ScrollPane sp = getControl();
99 sp.setHvalue(sp.getHmin());
100 sp.setVvalue(sp.getVmin());
101 }
102 void verticalEnd() {
103 ScrollPane sp = getControl();
104 sp.setHvalue(sp.getHmax());
105 sp.setVvalue(sp.getVmax());
106 }
107
108
109 public void contentDragged(double deltaX, double deltaY) {
110 // negative when dragged to the right/bottom
111 ScrollPane scroll = getControl();
112 if (!scroll.isPannable()) return;
113 if (deltaX < 0 && scroll.getHvalue() != 0 || deltaX > 0 && scroll.getHvalue() != scroll.getHmax()) {
114 scroll.setHvalue(scroll.getHvalue() + deltaX);
115 }
116 if (deltaY < 0 && scroll.getVvalue() != 0 || deltaY > 0 && scroll.getVvalue() != scroll.getVmax()) {
117 scroll.setVvalue(scroll.getVvalue() + deltaY);
118 }
119 }
120
121 /***************************************************************************
122 * *
123 * Key event handling *
124 * *
125 **************************************************************************/
126
127 static final String TRAVERSE_DEBUG = "TraverseDebug";
128 static final String HORIZONTAL_UNITDECREMENT = "HorizontalUnitDecrement";
129 static final String HORIZONTAL_UNITINCREMENT = "HorizontalUnitIncrement";
130 static final String VERTICAL_UNITDECREMENT = "VerticalUnitDecrement";
131 static final String VERTICAL_UNITINCREMENT = "VerticalUnitIncrement";
132 static final String VERTICAL_PAGEDECREMENT = "VerticalPageDecrement";
133 static final String VERTICAL_PAGEINCREMENT = "VerticalPageIncrement";
134 static final String VERTICAL_HOME = "VerticalHome";
135 static final String VERTICAL_END = "VerticalEnd";
136
137 /**
138 * We manually handle focus traversal keys due to the ScrollPane binding
139 * the left/right/up/down keys specially.
140 */
141 protected static final List<KeyBinding> SCROLL_PANE_BINDINGS = new ArrayList<>();
142 static {
143 // TODO XXX DEBUGGING ONLY
144 SCROLL_PANE_BINDINGS.add(new KeyBinding(F4, TRAVERSE_DEBUG).alt().ctrl().shift());
145
146 SCROLL_PANE_BINDINGS.add(new KeyBinding(LEFT, HORIZONTAL_UNITDECREMENT));
147 SCROLL_PANE_BINDINGS.add(new KeyBinding(RIGHT, HORIZONTAL_UNITINCREMENT));
148
149 SCROLL_PANE_BINDINGS.add(new KeyBinding(UP, VERTICAL_UNITDECREMENT));
150 SCROLL_PANE_BINDINGS.add(new KeyBinding(DOWN, VERTICAL_UNITINCREMENT));
151
152 SCROLL_PANE_BINDINGS.add(new KeyBinding(PAGE_UP, VERTICAL_PAGEDECREMENT));
153 SCROLL_PANE_BINDINGS.add(new KeyBinding(PAGE_DOWN, VERTICAL_PAGEINCREMENT));
154 SCROLL_PANE_BINDINGS.add(new KeyBinding(SPACE, VERTICAL_PAGEINCREMENT));
155
156 SCROLL_PANE_BINDINGS.add(new KeyBinding(HOME, VERTICAL_HOME));
157 SCROLL_PANE_BINDINGS.add(new KeyBinding(END, VERTICAL_END));
158 }
159
160 protected /*final*/ String matchActionForEvent(KeyEvent e) {
161 //TODO - untested code doesn't seem to get triggered (key eaten?)
162 String action = super.matchActionForEvent(e);
163 if (action != null) {
164 if (e.getCode() == LEFT) {
165 if (getControl().getEffectiveNodeOrientation() == NodeOrientation.RIGHT_TO_LEFT) {
166 action = "HorizontalUnitIncrement";
167 }
168 } else if (e.getCode() == RIGHT) {
169 if (getControl().getEffectiveNodeOrientation() == NodeOrientation.RIGHT_TO_LEFT) {
170 action = "HorizontalUnitDecrement";
171 }
172 }
173 }
174 return action;
175 }
176
177 @Override protected void callAction(String name) {
178 switch (name) {
179 case HORIZONTAL_UNITDECREMENT:
180 horizontalUnitDecrement();
181 break;
182 case HORIZONTAL_UNITINCREMENT:
183 horizontalUnitIncrement();
184 break;
185 case VERTICAL_UNITDECREMENT:
186 verticalUnitDecrement();
187 break;
188 case VERTICAL_UNITINCREMENT:
189 verticalUnitIncrement();
190 break;
191 case VERTICAL_PAGEDECREMENT:
192 verticalPageDecrement();
193 break;
194 case VERTICAL_PAGEINCREMENT:
195 verticalPageIncrement();
196 break;
197 case VERTICAL_HOME:
198 verticalHome();
199 break;
200 case VERTICAL_END:
201 verticalEnd();
202 break;
203 default :
204 super.callAction(name);
205 break;
206 }
207 }
208
209 /***************************************************************************
210 * *
211 * Mouse event handling *
212 * *
213 **************************************************************************/
214
215 public void mouseClicked() {
216 getControl().requestFocus();
217 }
218
219 @Override public void mousePressed(MouseEvent e) {
220 super.mousePressed(e);
221 getControl().requestFocus();
222 }
223 }
|
1 /*
2 * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.javafx.scene.control.behavior;
27
28 import javafx.scene.control.ScrollBar;
29 import javafx.scene.control.ScrollPane;
30 import com.sun.javafx.scene.control.inputmap.InputMap;
31 import javafx.scene.input.MouseEvent;
32 import javafx.scene.control.skin.ScrollPaneSkin;
33
34 import java.util.Optional;
35
36 import static javafx.scene.input.KeyCode.DOWN;
37 import static javafx.scene.input.KeyCode.LEFT;
38 import static javafx.scene.input.KeyCode.PAGE_DOWN;
39 import static javafx.scene.input.KeyCode.PAGE_UP;
40 import static javafx.scene.input.KeyCode.RIGHT;
41 import static javafx.scene.input.KeyCode.SPACE;
42 import static javafx.scene.input.KeyCode.UP;
43 import static javafx.scene.input.KeyCode.HOME;
44 import static javafx.scene.input.KeyCode.END;
45
46
47 /**
48 * Behavior for ScrollPane.
49 *
50 * TODO: the function variables are a poor way to couple to the rest of
51 * the system. This technique avoids a direct dependency on the skin class.
52 * However, this should really be coupled through the control itself instead
53 * of directly to the skin.
54 */
55 public class ScrollPaneBehavior extends BehaviorBase<ScrollPane> {
56
57 private final InputMap<ScrollPane> inputMap;
58
59 /***************************************************************************
60 * *
61 * Constructors *
62 * *
63 **************************************************************************/
64
65 public ScrollPaneBehavior(ScrollPane scrollPane) {
66 super(scrollPane);
67
68 // create a map for scrollpane-specific mappings (this reuses the default
69 // InputMap installed on the control, if it is non-null, allowing us to pick up any user-specified mappings)
70 inputMap = createInputMap();
71
72 // scrollpane-specific mappings for key and mouse input
73 addDefaultMapping(inputMap,
74 new InputMap.KeyMapping(LEFT, e -> rtl(scrollPane, this::horizontalUnitIncrement, this::horizontalUnitDecrement)),
75 new InputMap.KeyMapping(RIGHT, e -> rtl(scrollPane, this::horizontalUnitDecrement, this::horizontalUnitIncrement)),
76
77 new InputMap.KeyMapping(UP, e -> verticalUnitDecrement()),
78 new InputMap.KeyMapping(DOWN, e -> verticalUnitIncrement()),
79
80 new InputMap.KeyMapping(PAGE_UP, e -> verticalPageDecrement()),
81 new InputMap.KeyMapping(PAGE_DOWN, e -> verticalPageIncrement()),
82 new InputMap.KeyMapping(SPACE, e -> verticalPageIncrement()),
83
84 new InputMap.KeyMapping(HOME, e -> verticalHome()),
85 new InputMap.KeyMapping(END, e -> verticalEnd()),
86
87 new InputMap.MouseMapping(MouseEvent.MOUSE_PRESSED, this::mousePressed)
88 );
89 }
90
91
92
93 /***************************************************************************
94 * *
95 * Functions *
96 * *
97 **************************************************************************/
98
99 @Override public InputMap<ScrollPane> getInputMap() {
100 return inputMap;
101 }
102
103 public void horizontalUnitIncrement() {
104 getHorizontalScrollBar().ifPresent(ScrollBar::increment);
105 }
106 public void horizontalUnitDecrement() {
107 getHorizontalScrollBar().ifPresent(ScrollBar::decrement);
108 }
109 public void verticalUnitIncrement() {
110 getVerticalScrollBar().ifPresent(ScrollBar::increment);
111 }
112 void verticalUnitDecrement() {
113 getVerticalScrollBar().ifPresent(ScrollBar::decrement);
114 }
115 void horizontalPageIncrement() {
116 getHorizontalScrollBar().ifPresent(ScrollBar::increment);
117 }
118 void horizontalPageDecrement() {
119 getHorizontalScrollBar().ifPresent(ScrollBar::decrement);
120 }
121 void verticalPageIncrement() {
122 getVerticalScrollBar().ifPresent(ScrollBar::increment);
123 }
124 void verticalPageDecrement() {
125 getVerticalScrollBar().ifPresent(ScrollBar::decrement);
126 }
127 void verticalHome() {
128 ScrollPane sp = getNode();
129 sp.setHvalue(sp.getHmin());
130 sp.setVvalue(sp.getVmin());
131 }
132 void verticalEnd() {
133 ScrollPane sp = getNode();
134 sp.setHvalue(sp.getHmax());
135 sp.setVvalue(sp.getVmax());
136 }
137
138 private Optional<ScrollBar> getVerticalScrollBar() {
139 return Optional.ofNullable(((ScrollPaneSkin)getNode().getSkin()).getVerticalScrollBar());
140 }
141
142 private Optional<ScrollBar> getHorizontalScrollBar() {
143 return Optional.ofNullable(((ScrollPaneSkin)getNode().getSkin()).getHorizontalScrollBar());
144 }
145
146
147 /***************************************************************************
148 * *
149 * Mouse event handling *
150 * *
151 **************************************************************************/
152
153 public void mousePressed(MouseEvent e) {
154 getNode().requestFocus();
155 }
156 }
|