2010-11-28 33 views
11

JScrollPane内にJTextAreaコンポーネントがあり、テキストエリアは編集できません。上下の矢印キーでテキスト領域をスクロールすることができます(つまり、矢印キーを押すとテキスト領域が1行スクロールします)。どのようにこれを達成するための任意のアイデアですか?JScrollPane矢印キーを使用したスクロール

+1

私はあなたが答えを受け入れたことは知っていますが、必ずしもカスタムコードを書く必要はありません。私の新しく追加された提案をチェックしてください。 – camickr

+0

ええ、両方の答えからの知識を組み合わせることで、この種の問題はうまく解決できます。残念ながら、複数の回答を受け入れることはできません; – JooMing

答えて

13

はいキーバインドがありますが、必ずしも独自のアクションを作成する必要はありません。スイングコンポーネントには、頻繁に再利用できるデフォルトのアクションが付属しています。

これらのアクションの完全な一覧については、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

本当に有益な情報に感謝します。 –

+0

このキーバインディングのリンクは非常に便利です!既存のアクションを再利用すると、維持する。 – JooMing

0

JScrollPaneにKeyListenerを追加する必要があります。

+1

このタイプの状況では、キーリスナーよりもキーバインディングを使用するほうが常に良いです。 –

4

JTextAreaが編集不可でフォーカス不可能な場合、矢印キーに応答しません。これを回避するための正式な方法があるかどうかはわかりませんが、それに対応させる方法の1つは、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

大した問題は、ページアップ/ページ管理キーが機能していなかったことです。テキストエリアをフォーカス可能に設定し、WHEN_IN_FOCUSED_WINDOWの代わりにWHEN_FOCUSEDの入力マップを使用しました。ありがとうございました! – JooMing

+0

または、増分/減分量がビューポートの高さになる点を除いて、上記と同じキーバインドとしてページアップとページダウンを追加できます。 –

+1

常にカスタムアクションを作成する必要はありません。私の提案を参照してください。 – camickr

0

はちょうどこの問題に出くわしたと回答は、右方向への溶液のいくつかのビットを私を駆動するのに有用であった一方、それ以来変更されている可能性があります。 - それは変更する必要のあるJScrollPaneインスタンスのInputMapでした - actionMapKeysは、 "unitScrollX"および/または "scrollX"(X = Down、Up、Left、Right)でなければなりませんでした。 。それらはBasicScrollPaneUIにあります。

関連する問題