Прокрутка JScrollPane с помощью клавиш со стрелками
У меня есть компонент JTextArea внутри JScrollPane, и текстовая область не редактируется. Я хотел бы включить прокрутку текстовой области с помощью клавиш со стрелками вверх и вниз (то есть нажатие клавиш со стрелками будет прокручивать текстовую область на одну строку). Есть идеи, как этого добиться?
4 ответов:
Да, привязка ключей-это правильный путь, но вам не всегда нужно создавать свои собственные действия. Компоненты Swing поставляются с действиями по умолчанию, которые можно часто использовать повторно.
Полный список этих действий приведен в разделе привязки ключей.Теперь, когда вы знаете название действия, вы можете просто привязать его к нажатию клавиши:
JScrollBar vertical = scrollPane.getVerticalScrollBar(); InputMap im = vertical.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); im.put(KeyStroke.getKeyStroke("DOWN"), "positiveUnitIncrement"); im.put(KeyStroke.getKeyStroke("UP"), "negativeUnitIncrement");
Если JTextArea не редактируется и не фокусируется, он не будет реагировать на клавиши со стрелками. Я не уверен, что существует канонический способ обойти это,но один из способов заставить его реагировать-это установить его привязку ключа, чтобы отвечать на клавиши up и down, когда JTextArea находится в окне focusable. Пример этого выглядит следующим образом:
import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import javax.swing.*; import javax.swing.text.JTextComponent; @SuppressWarnings("serial") public class TestScrollingArea extends JPanel { private static final String UP = "Up"; private static final String DOWN = "Down"; private JTextArea area = new JTextArea(20, 40); private JScrollPane scrollPane = new JScrollPane(area); public TestScrollingArea() { // make textarea non-editable and non-focusable area.setEditable(false); area.setFocusable(false); area.setWrapStyleWord(true); area.setLineWrap(true); add(scrollPane); // fill area with letters for (int i = 0; i < 10; i++) { for (int j = 0; j < 100; j++) { area.append("abcdefg "); } } // have JTextArea tell us how tall a line of text is. int scrollableIncrement = area.getScrollableUnitIncrement(scrollPane.getVisibleRect(), SwingConstants.VERTICAL, 1); // add key bindings to the JTextArea int condition = JTextComponent.WHEN_IN_FOCUSED_WINDOW; InputMap inMap = area.getInputMap(condition); ActionMap actMap = area.getActionMap(); inMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), UP); inMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), DOWN); actMap.put(UP, new UpDownAction(UP, scrollPane.getVerticalScrollBar().getModel(), scrollableIncrement)); actMap.put(DOWN, new UpDownAction(DOWN, scrollPane.getVerticalScrollBar().getModel(), scrollableIncrement)); } // Action for our key binding to perform when bound event occurs private class UpDownAction extends AbstractAction { private BoundedRangeModel vScrollBarModel; private int scrollableIncrement; public UpDownAction(String name, BoundedRangeModel model, int scrollableIncrement) { super(name); this.vScrollBarModel = model; this.scrollableIncrement = scrollableIncrement; } @Override public void actionPerformed(ActionEvent ae) { String name = getValue(AbstractAction.NAME).toString(); int value = vScrollBarModel.getValue(); if (name.equals(UP)) { value -= scrollableIncrement; vScrollBarModel.setValue(value); } else if (name.equals(DOWN)) { value += scrollableIncrement; vScrollBarModel.setValue(value); } } } private static void createAndShowUI() { JFrame frame = new JFrame("TestScrollingArea"); frame.getContentPane().add(new TestScrollingArea()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String[] args) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { createAndShowUI(); } }); } }
Только что столкнулся с этой проблемой, и хотя ответы были полезны для того, чтобы направить меня в нужное русло, некоторые фрагменты решения, возможно, изменились с тех пор. Это сработало для меня с последующими изменениями.: - это была InputMap экземпляра JScrollPane, который должен был быть изменен - actionMapKeys должны были быть: "unitScrollX" и / или" scrollX " (X= вниз, вверх, влево, вправо). Они живут в BasicScrollPaneUI.
Comments