(事情在描述后的代码中会很清楚)
我有一个包含 JScrollBar、JTextArea、JTextFields、JButtons 和其他一些东西的程序。(我只添加了SSCCE代码)
好的,我为 JScrollBar 的左右 JButtons 添加了键绑定,我使用了getInputMap
,并getActionMap
实现了这一点。
如果我的 GUI 程序中的 JScrollBar 没有 JTextField 或 JTextArea 等可编辑组件,那么 keyStrokesKeyEvent.VK_LEFT
将KeyEvent.VK_RIGHT
正常工作(如预期的那样)
但是,如果我有一个带有 JScrollBar 的可编辑组件,那么它不会响应KeyEvent.VK_LEFT
并且KeyEvent.VK_RIGHT
(不是预期的)为什么会发生这种情况!?更奇怪的
是,如果我选择不同的 keyStrokes 来绑定,例如for left 和for right,它会起作用!现在为什么?KeyEvent.VK_S
KeyEvent.VK_F
如何修复,如何在可编辑组件共存时为 JScrollBar JButtons 进行左右箭头键绑定?
这是 SSCCE 风格的两个工作代码。第一个包含没有可编辑组件的 JScrollBar,第二个包含带有 JTextArea 的 JScrollBar。
第一个可以正常工作,即它将响应键盘的左右箭头。(它不包含可编辑的组件)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ScrollTest extends JPanel
{
JPanel panel;
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);
this.setLayout(new BorderLayout());
this.add(panel, BorderLayout.NORTH);
}
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)
更奇怪的是替换
为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();
}
});
}
}