下面的例子中:
- ctrl + 左方向键:水平滚动条向左移
- ctrl + 右方向键:水平滚动条向右移
- ctrl + 上方向键:垂直滚动条向上移
- ctrl + 下方向键:垂直滚动条向下移
对于没有滚动条的控件,如果Button,上面的四个按键没有任何效果。
AdjustType:
- UNIT:效果相当于点击滚动条两端的箭头,移动的少。
- BLOCK:效果相当于点击滚动条上的空白,移动的多。
import javafx.event.EventHandler;
import javafx.scene.AccessibleAction;
import javafx.scene.AccessibleAttribute;
import javafx.scene.control.Control;
import javafx.scene.control.ScrollBar;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.input.KeyEvent;
/**
* Add key control for the scroll bar of any JavaFx control.
*
* <code>
* TableView<!--?--> tableView = new TableView<>();
*
* // The first parameter can be any JavaFX control.
* // The second parameter specifies adjust type.
* tableView.setOnKeyPressed(new ControlScrollBarHandler(tableView, ADJUST_TYPE.UNIT));
*
* // Use default adjust type, which is AdjustType.BLOCK.
* tableView.setOnKeyPressed(new ControlScrollBarHandler(tableView));
* </code>
*
* @author alzhang
*/
public class ControlScrollBarHandler implements EventHandler<keyevent> {
/**
* The increment type of scroll bar.
*
* @author alzhang
*/
public enum AdjustType {
/**
* Same as clicking the ARROW of scroll bar.
*/
UNIT,
/**
* Same as clicking the empty space of scroll bar.
*/
BLOCK;
}
/**
* Control + LEFT Arrow
*/
private static final KeyCombination SCROLL_LEFT =
new KeyCodeCombination(KeyCode.LEFT, KeyCombination.CONTROL_DOWN);
/**
* Control + RIGHT Arrow
*/
private static final KeyCombination SCROLL_RIGHT =
new KeyCodeCombination(KeyCode.RIGHT, KeyCombination.CONTROL_DOWN);
/**
* Control + UP Arrow
*/
private static final KeyCombination SCROLL_UP =
new KeyCodeCombination(KeyCode.UP, KeyCombination.CONTROL_DOWN);
/**
* Control + DOWN Arrow
*/
private static final KeyCombination SCROLL_DOWN =
new KeyCodeCombination(KeyCode.DOWN, KeyCombination.CONTROL_DOWN);
private final Control control;
private final AdjustType adjustType;
private ScrollBar hScrollBar;
private ScrollBar vScrollBar;
/**
* Construct an instance.
*
* @param control a control.
*/
public ControlScrollBarHandler(Control control) {
this(control, AdjustType.BLOCK);
}
/**
* Construct an instance.
*
* @param control a control.
* @param adjustType indicate how to adjust scroll bar.
*/
public ControlScrollBarHandler(Control control, AdjustType adjustType) {
super();
this.control = control;
this.adjustType = adjustType;
// JavaFX creates scroll bar when initialize skin.
if (control.skinProperty().get() != null) {
initScrollBar();
}
// Update scroll bar when skin is changed.
control.skinProperty().addListener((observable, oldSkin, newSkin) -> {
initScrollBar();
});
}
private void initScrollBar() {
hScrollBar = ScrollBar.class.cast(control.queryAccessibleAttribute(AccessibleAttribute.HORIZONTAL_SCROLLBAR));
vScrollBar = ScrollBar.class.cast(control.queryAccessibleAttribute(AccessibleAttribute.VERTICAL_SCROLLBAR));
}
@Override
public void handle(KeyEvent keyEvent) {
if (hScrollBar == null || vScrollBar == null) {
return;
}
if (SCROLL_LEFT.match(keyEvent) && hScrollBar != null) {
adjustScrollBar(hScrollBar, false);
} else if (SCROLL_RIGHT.match(keyEvent) && hScrollBar != null) {
adjustScrollBar(hScrollBar, true);
} else if (SCROLL_UP.match(keyEvent) && vScrollBar != null) {
adjustScrollBar(vScrollBar, false);
} else if (SCROLL_DOWN.match(keyEvent) && vScrollBar != null) {
adjustScrollBar(vScrollBar, true);
}
}
private void adjustScrollBar(ScrollBar scrollBar, boolean isIncrement) {
if (isIncrement) {
if (AdjustType.UNIT.equals(adjustType)) {
scrollBar.executeAccessibleAction(AccessibleAction.INCREMENT);
} else {
scrollBar.executeAccessibleAction(AccessibleAction.BLOCK_INCREMENT);
}
} else {
if (AdjustType.UNIT.equals(adjustType)) {
scrollBar.executeAccessibleAction(AccessibleAction.DECREMENT);
} else {
scrollBar.executeAccessibleAction(AccessibleAction.BLOCK_DECREMENT);
}
}
}
}