Java 我可以在JScrollPane内的JTextArea中使用按键组合向上或向下滚动吗?

Java 我可以在JScrollPane内的JTextArea中使用按键组合向上或向下滚动吗?,java,swing,jscrollpane,jtextarea,key-bindings,Java,Swing,Jscrollpane,Jtextarea,Key Bindings,如果文本区域有焦点,当然PgUp和PgDn键工作正常,但我希望使用键绑定向上或向下滚动它,将焦点保留在原来的位置,而不是将其移动到文本区域并返回 因此,我将带有CTRL\u DOWN\u掩码的VK\u PAGEDOWN映射到一个菜单项,希望当用户按下CTRL+PgDn时,程序将文本区域滚动20行 但是,虽然txaOutput.getLineCount()返回文本区域中的行数,但我找不到方法将插入符号行设置为该数字减去20txaOutput.setCaretPosition(inti)在字节号i处

如果文本区域有焦点,当然PgUp和PgDn键工作正常,但我希望使用键绑定向上或向下滚动它,将焦点保留在原来的位置,而不是将其移动到文本区域并返回

因此,我将带有CTRL\u DOWN\u掩码的VK\u PAGEDOWN映射到一个菜单项,希望当用户按下CTRL+PgDn时,程序将文本区域滚动20行

但是,虽然
txaOutput.getLineCount()
返回文本区域中的行数,但我找不到方法将插入符号行设置为该数字减去20
txaOutput.setCaretPosition(inti)
在字节号
i
处设置插入符号

我所做的是假的,但它确实会滚动(向上翻页是相同的,除了
-scrollBytes
):

是否有办法将插入符号设置为
JScrollPane
JTextArea
中的特定行号

编辑

文本区域包含每行3到11个字母的单个单词

编辑2

这就是为什么它是
操作
而不是
操作执行

import java.awt.event.ActionEvent;
import javax.swing.*;
import static javax.swing.KeyStroke.getKeyStroke;

public abstract class KeyBoundMenuItem extends JMenuItem{

  public abstract void action(ActionEvent e);


      public KeyBoundMenuItem(String actionMapKey, int key, int mask)
      {
        Action myAction = new AbstractAction()
        {
          @Override public void actionPerformed(ActionEvent e)
          {
            action(e);
          }
        };  

        setAction(myAction);

        getInputMap(WHEN_IN_FOCUSED_WINDOW)
                      .put(getKeyStroke(key, mask),actionMapKey);
        getActionMap().put(                        actionMapKey, myAction);

      }
    }
编辑3

可以使用此选项而不是
KeyBoundMenuItem

  public static void shortcut(JMenuItem item, int mnem, int mods, int key)
  {  
    item.setMnemonic(mnem);
    item.setAccelerator(getKeyStroke(key,mods));
  }
但是有类似类的代码
keybundbutton
。很容易在一天的晚些时候做出改变

编辑4

以下是需要向上或向下滚动的文本类型:

有没有办法将插入符号设置为特定的行号

看看这个班。方法如下:

  • getLineAtCaret()
  • gotoStartOfLine(…)
  • 应该允许你做你想做的事。即向下滚动,您可以执行以下操作:

    int currentLine = RXTextUtilities.getLineAtCaret(textArea);
    RXTextUtilities.gotoStartOfLine(textArea, currentLine + 10);
    

    多亏了@camickr,这里的工作原理是一样的(除了
    -
    而不是
    +

    PageDown = new KeyBoundMenuItem("PAGEDOWN", VK_PAGE_DOWN, CTRL_DOWN_MASK) 
    {
      @Override
      public void action(ActionEvent e) 
      {
          int currentLine = RXTextUtilities.getLineAtCaret(txaOutput);
          RXTextUtilities.gotoStartOfLine(
            txaOutput, 
            currentLine + RXTextUtilities.maxLinesVisibleInWindow(txaOutput));
      }
    };
    
    我可能应该修改这段代码以反映他的合理批评,即我不必创建
    抽象类来完成键绑定,但它没有损坏。(我可能有一天会去做它…)

    我甚至想出了(通过研究他的)如何在不使用常量的情况下滚动窗口(28,见注释):


    考虑创建和发布A。我想知道这个类中的一些方法是否可以帮助你。我认为最好的解决方法是从JTestTaReA获取文本并手动扫描新行。保留所有新行字符的列表和它们在文本中的位置,直到达到当前插入符号位置或期望行数为止。ever更向下。然后您可以在所需换行符上设置插入符号位置。您应该实现
    actionPerformed(…)
    ,而不是“action(…)”@Knox:这行不通,因为如果设置正确,当文本行几乎与可见组件的宽度相等时,JTextArea中的文本将自动换行,当这种情况发生时,将创建一个没有任何换行符的新行。Rob,你就是那个人!我毫不怀疑这会对我起作用,因为你的钱是对的。像往常一样,我在t我的一天结束了/rope。明天将查看文本实用程序。@camickr--改变了我的想法。考虑到实现TCA有多么容易,所以尝试了TextUtilities。效果很好。如果我有一份工资单,我会把你放在工资单上!只添加了这两行:
    int currentLine=rxtextutilities.RxtUtilities.GetLineatCarte(txaOutput);rxtextutilities.rxtextutilities.gotoStartOfLine(txaOutput,currentLine+28);
    和page up类似。@DSlomer64,不知道为什么要使用
    rxtutilities.rxtextutilities…
    。所有的方法都是静态方法,所以不需要创建类的实例,只需使用
    rxtextutilities.??(…)
    。我打错了(忘记了“RX”)在我的原始代码中,我已经修复了它。没有经过思考就完成了。想回家吗!谢谢你的提醒。我没有创建类的实例,只是将方法用作静态。限定符是包名加类名。对Netbeans感到失望——它只需要清理和构建。我使用的是:
    int currentLine=RXTextUtilities.getLineAtCaret(txaOutput);RXTextUtilities.gotoStartOfLine(txaOutput,currentLine+28);
    PageDown = new KeyBoundMenuItem("PAGEDOWN", VK_PAGE_DOWN, CTRL_DOWN_MASK) 
    {
      @Override
      public void action(ActionEvent e) 
      {
          int currentLine = RXTextUtilities.getLineAtCaret(txaOutput);
          RXTextUtilities.gotoStartOfLine(
            txaOutput, 
            currentLine + RXTextUtilities.maxLinesVisibleInWindow(txaOutput));
      }
    };
    
      public static int maxLinesVisibleInWindow(JTextComponent component)
      {
          Container container = getAncestorOfClass(JViewport.class, component);
    
        if (container == null) return 0;
    
        JViewport   viewport        = (JViewport)container;
        int         extentHeight    = viewport.getExtentSize().height;
        FontMetrics fm              = component.getFontMetrics(component.getFont());
        int         characterHeight = fm.getHeight();
    
        return (int)extentHeight/characterHeight - 1;
      }