2010-11-28 60 views
11

我在JScrollPane中有一个JTextArea组件,文本区域不可编辑。我想使用向上和向下箭头键来滚动文本区域(即按方向键将滚动文本区域一行)。任何想法如何实现这一目标?JScrollPane使用箭头键滚动

+1

我知道你已经接受了答案,但你并不总是需要编写自定义代码。看看我新增的建议。 – camickr 2010-11-29 00:21:23

+0

是的,通过结合两种答案的知识,这种问题可以很好地解决。不幸的是,它不可能接受多个答案;( – JooMing 2010-11-29 07:31:30

回答

13

是键绑定是要走的路,但你并不总是需要创建自己的操作。 Swing组件带有可以经常重用的默认操作。

请参阅Key Bindings了解这些操作的完整列表。

现在你知道操作名称你可以把它绑定到一个按键:

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"); 
0

您应该将KeyListener添加到您的JScrollPane。

+1

在这种情况下,使用键绑定比关键的监听器好几乎总是最好的 – 2010-11-28 19:49:29

4

如果JTextArea不可编辑且不可调焦,则不会响应箭头键。我不确定是否有一种规范的方法来解决这个问题,但使其响应的一种方法是设置其键绑定,以在JTextArea处于可调焦窗口时响应向上和向下键。一个例子如下:

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(); 
      } 
     }); 
    } 
} 
+0

太好了!一个小问题是pageup/pagedown键不起作用。将文本区域设置为可聚焦的,并使用WHEN_FOCUSED的输入映射而不是WHEN_IN_FOCUSED_WINDOW。非常感谢! – JooMing 2010-11-28 21:21:02

0

过这样的问题就来了,而答案是让我正确的方向解决方案的某些位有用此后可能已经发生了变化。它为我工作,他与他下面的变化: - 这是JScrollPane实例的InputMap必须更改 - actionMapKeys必须是:“unitScrollX”和/或“scrollX”(X =下,上,左,右) 。它们驻留在BasicScrollPaneUI中。