IDEA-178054: update tree actions to move selection (page up/down + home/end)

This commit is contained in:
Sergey Malenkov
2019-04-16 13:35:07 +03:00
parent 3a1e2378c7
commit 0a07d042c4
3 changed files with 65 additions and 11 deletions
@@ -721,6 +721,8 @@ public final class TreeUtil {
@SuppressWarnings("HardCodedStringLiteral")
public static void installActions(@NotNull final JTree tree) {
TreeUI ui = tree.getUI();
if (ui != null && ui.getClass().getName().equals("com.intellij.ui.tree.ui.DefaultTreeUI")) return;
tree.getActionMap().put("scrollUpChangeSelection", new AbstractAction() {
@Override
public void actionPerformed(final ActionEvent e) {
@@ -733,8 +735,6 @@ public final class TreeUtil {
movePageDown(tree);
}
});
TreeUI ui = tree.getUI();
if (ui != null && ui.getClass().getName().equals("com.intellij.ui.tree.ui.DefaultTreeUI")) return;
tree.getActionMap().put("selectPrevious", new AbstractAction() {
@Override
public void actionPerformed(final ActionEvent e) {
@@ -256,6 +256,7 @@ public final class DefaultTreeUI extends BasicTreeUI {
protected void installKeyboardActions() {
super.installKeyboardActions();
TreeAction.installTo(tree.getActionMap());
TreeAction.installTo(tree.getInputMap(JComponent.WHEN_FOCUSED));
}
@Override
@@ -11,13 +11,29 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.plaf.UIResource;
import javax.swing.tree.TreePath;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.util.Arrays;
import java.awt.event.KeyEvent;
import java.util.List;
import static java.util.Arrays.asList;
import static javax.swing.KeyStroke.getKeyStroke;
abstract class TreeAction extends AbstractAction implements UIResource {
private static final List<TreeAction> ACTIONS = Arrays.asList(
new TreeAction(TreeActions.Up.ID) {
private static final List<TreeAction> ACTIONS = asList(
new TreeAction(TreeActions.Home.ID, getKeyStroke(KeyEvent.VK_HOME, 0)) {
@Override
void actionPerformed(@NotNull JTree tree, @Nullable TreePath path) {
scrollAndSetSelection(tree, 0);
}
},
new TreeAction(TreeActions.End.ID, getKeyStroke(KeyEvent.VK_END, 0)) {
@Override
void actionPerformed(@NotNull JTree tree, @Nullable TreePath path) {
scrollAndSetSelection(tree, tree.getRowCount() - 1);
}
},
new TreeAction(TreeActions.Up.ID, getKeyStroke(KeyEvent.VK_UP, 0), getKeyStroke(KeyEvent.VK_KP_UP, 0)) {
@Override
void actionPerformed(@NotNull JTree tree, @Nullable TreePath path) {
int row = tree.getRowForPath(path);
@@ -31,7 +47,7 @@ abstract class TreeAction extends AbstractAction implements UIResource {
}
}
},
new TreeAction(TreeActions.Down.ID) {
new TreeAction(TreeActions.Down.ID, getKeyStroke(KeyEvent.VK_DOWN, 0), getKeyStroke(KeyEvent.VK_KP_DOWN, 0)) {
@Override
void actionPerformed(@NotNull JTree tree, @Nullable TreePath path) {
int row = tree.getRowForPath(path);
@@ -45,7 +61,7 @@ abstract class TreeAction extends AbstractAction implements UIResource {
}
}
},
new TreeAction(TreeActions.Left.ID) {
new TreeAction(TreeActions.Left.ID, getKeyStroke(KeyEvent.VK_LEFT, 0), getKeyStroke(KeyEvent.VK_KP_LEFT, 0)) {
@Override
void actionPerformed(@NotNull JTree tree, @Nullable TreePath path) {
int row = tree.getRowForPath(path);
@@ -68,7 +84,7 @@ abstract class TreeAction extends AbstractAction implements UIResource {
}
}
},
new TreeAction(TreeActions.Right.ID) {
new TreeAction(TreeActions.Right.ID, getKeyStroke(KeyEvent.VK_RIGHT, 0), getKeyStroke(KeyEvent.VK_KP_RIGHT, 0)) {
@Override
void actionPerformed(@NotNull JTree tree, @Nullable TreePath path) {
int row = tree.getRowForPath(path);
@@ -82,11 +98,42 @@ abstract class TreeAction extends AbstractAction implements UIResource {
tree.expandPath(path);
}
}
},
new TreeAction(TreeActions.PageUp.ID, getKeyStroke(KeyEvent.VK_PAGE_UP, 0)) {
@Override
void actionPerformed(@NotNull JTree tree, @Nullable TreePath path) {
Rectangle bounds = tree.getPathBounds(path);
if (path == null || bounds == null) {
scrollAndSetSelection(tree, 0);
}
else {
int height = Math.max(tree.getVisibleRect().height - bounds.height, 1);
TreePath next = tree.getClosestPathForLocation(bounds.x, bounds.y - height);
if (next != null && !next.equals(path)) scrollAndSetSelection(tree, next);
}
}
},
new TreeAction(TreeActions.PageDown.ID, getKeyStroke(KeyEvent.VK_PAGE_DOWN, 0)) {
@Override
void actionPerformed(@NotNull JTree tree, @Nullable TreePath path) {
Rectangle bounds = tree.getPathBounds(path);
if (path == null || bounds == null) {
scrollAndSetSelection(tree, tree.getRowCount() - 1);
}
else {
int height = Math.max(tree.getVisibleRect().height - bounds.height, 1);
TreePath next = tree.getClosestPathForLocation(bounds.x, bounds.y + bounds.height + height);
if (next != null && !next.equals(path)) scrollAndSetSelection(tree, next);
}
}
}
);
private final String name;
private final List<KeyStroke> keys;
TreeAction(@NotNull String name) {
super(name);
TreeAction(@NotNull String name, @NotNull KeyStroke... keys) {
this.name = name;
this.keys = asList(keys);
}
abstract void actionPerformed(@NotNull JTree tree, @Nullable TreePath path);
@@ -103,7 +150,13 @@ abstract class TreeAction extends AbstractAction implements UIResource {
static void installTo(@NotNull ActionMap map) {
Object[] keys = map.keys();
if (keys != null && keys.length != 0) return; // actions are already installed
for (TreeAction action : ACTIONS) map.put(action.getValue(NAME), action);
for (TreeAction action : ACTIONS) map.put(action.name, action);
}
static void installTo(@NotNull InputMap map) {
Object[] keys = map.keys();
if (keys != null && keys.length != 0) return; // keys for actions are already installed
for (TreeAction action : ACTIONS) for (KeyStroke key : action.keys) map.put(key, action.name);
}
static void scrollAndSetSelection(@NotNull JTree tree, int row) {