Java 为什么JScrollBar没有';与可编辑组件共存时,是否不响应箭头键?

Java 为什么JScrollBar没有';与可编辑组件共存时,是否不响应箭头键?,java,swing,binding,keystroke,jscrollbar,Java,Swing,Binding,Keystroke,Jscrollbar,(描述后,代码中的内容会很清楚) 我有一个包含JScrollBar、JTextArea、JTextFields、jbutton和其他一些东西的程序。(我仅添加了SSCCE代码) 好的,我为JScrollBar的左右jbutton添加了键绑定,我使用getInputMap和getActionMap实现了这一点 如果我的GUI程序中有JScrollBar,但没有可编辑的组件,如JTextField或JTextArea,则击键KeyEvent.VK_LEFT和KeyEvent.VK_RIGHT将正常工

(描述后,代码中的内容会很清楚)

我有一个包含JScrollBar、JTextArea、JTextFields、jbutton和其他一些东西的程序。(我仅添加了SSCCE代码)

好的,我为JScrollBar的左右jbutton添加了键绑定,我使用
getInputMap
getActionMap
实现了这一点

如果我的GUI程序中有JScrollBar,但没有可编辑的组件,如JTextField或JTextArea,则击键
KeyEvent.VK_LEFT
KeyEvent.VK_RIGHT
将正常工作(如预期)

但是,如果我有一个带有JScrollBar的可编辑组件,那么它将不会响应
KeyEvent.VK_LEFT
KeyEvent.VK_RIGHT
(不期望)为什么会发生这种情况
更奇怪的事情是,如果我选择不同的击键进行绑定,比如左键选择
KeyEvent.VK_S
,右键选择
KeyEvent.VK_F
,它会工作!!现在为什么

如何修复,如何在可编辑组件共存时为JScrollBar JButtons进行左右箭头键绑定

这是SSCCE样式的两个工作代码。第一个包含不带可编辑组件的JScrollBar,第二个包含带JTextArea的JScrollBar

第一个将正常工作,即它将响应键盘的左箭头和右箭头。(它不包含可编辑组件)

第二个将不起作用,即它不会响应键盘的左箭头和右箭头。(它确实包含可编辑组件-一个JTextArea)

更奇怪的事情
KeyEvent.VK_LEFT
替换为
KeyEvent.VK_S
,将
KeyEvent.VK_RIGHT
替换为
KeyEvent.VK_F
。现在S代表左边,F代表右边!为什么它不适用于左箭头和右箭头

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ScrollTest extends JPanel
{

   JPanel panel;
   JPanel panel2;
   JScrollBar scrollBar;
   JButton sliderLeftButton;
   JButton sliderRightButton;

   public ScrollTest()
   {
      scrollBar = new JScrollBar(JScrollBar.HORIZONTAL, 0, 6, 0, 300);

      sliderLeftButton = (JButton) scrollBar.getAccessibleContext().getAccessibleChild(1);
      sliderLeftButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "leftmove");
      sliderLeftButton.getActionMap().put("leftmove", leftmove);

      sliderRightButton = (JButton) scrollBar.getAccessibleContext().getAccessibleChild(0);
      sliderRightButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "rightmove");
      sliderRightButton.getActionMap().put("rightmove", rightMove);

      panel = new JPanel(new GridLayout(2, 0));
      panel.add(scrollBar);

      panel2 = new JPanel(new GridLayout(1, 0));
      panel2.add(new JTextArea(50, 10));

      this.setLayout(new BorderLayout());
      this.add(panel, BorderLayout.NORTH);
      this.add(panel2, BorderLayout.SOUTH);
   }
   AbstractAction leftmove = new AbstractAction()
   {
      @Override
      public void actionPerformed(ActionEvent ae)
      {
         int increment = scrollBar.getBlockIncrement();
         int current = scrollBar.getValue();
         current -= increment;
         scrollBar.setValue(current);
         System.out.println("left");
      }
   };
   AbstractAction rightMove = new AbstractAction()
   {
      @Override
      public void actionPerformed(ActionEvent ae)
      {
         int increment = scrollBar.getBlockIncrement();
         int current = scrollBar.getValue();
         current += increment;
         scrollBar.setValue(current);
         System.out.println("right");
      }
   };

   private static void createAndShowGUI()
   {
      JFrame frame;
      frame = new JFrame("Scroll Test");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setSize(880, 100);
      frame.add(new ScrollTest(), BorderLayout.CENTER);
      frame.setVisible(true);
   }

   public static void main(String[] args)
   {
      SwingUtilities.invokeLater(new Runnable()
      {
         public void run()
         {
            UIManager.put("swing.boldMetal", Boolean.FALSE);
            createAndShowGUI();
         }
      });
   }
}

这是因为JTextArea正在窃取您的按键:

    textPane.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "pressed RIGHT");
    textPane.getActionMap().put("pressed RIGHT", rightMove);

查看一下BasicTextUI.installKeyboardActions()

在我看来,您必须使用此属性
JComponent。在
InputMap
的聚焦窗口中
时。由于相同的
KeyBindings
thingy也应用于可编辑的
JTextField/JTextArea
,因此您必须为
getInputMap().put()保留此thingy为空。更简单地说,相同的键也绑定到可编辑的
JTextField/JTextArea
,因此当聚焦时
将优先于当聚焦窗口中的
时,IMHO,正如教程中所述:-)@Andrew最好编辑它,而不是讽刺英语误用,因为英语不是我的第一语言,这是我用英语表达事物的方式。我总是尽力做到最好。谢谢。默认情况下,可编辑组件需要基于键的导航。正如@nIcEcOw所详述的,将滚动条和可编辑组件的键绑定在一起是违反直觉的(将滚动更改为响应V或S或将可编辑组件滚动更改为V或S)。在可编辑组件中时,滚动条的移动由鼠标控制。
    textPane.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "pressed RIGHT");
    textPane.getActionMap().put("pressed RIGHT", rightMove);