(Все будет ясно в коде после описания)Почему JScrollBar не реагирует на нажатия клавиш стрелки, когда они сосуществуют с редактируемым компонентом?
У меня есть программа, которая содержит JScrollBar, JTextArea, JTextFields, JButtons и некоторые другие вещи. (Я добавил только коды SSCCE)
ОК, я добавил привязки клавиш для левого и правого JButtons JScrollBar, для этого я использовал getInputMap
и getActionMap
.
Если у меня есть JScrollBar в моей программе GUI без редактирования компонентов, таких как JTextField или JTextArea, то KEYSTROKES KeyEvent.VK_LEFT
и KeyEvent.VK_RIGHT
будет нормально работать (как и ожидалось)
Но если у меня есть редактируемый компонент с JScrollBar затем он не будет отвечать на KeyEvent.VK_LEFT
и KeyEvent.VK_RIGHT
(не ожидается), почему это происходит !?
Более странная вещь заключается в том, что если бы я выбрал разные ключевые клавиши для связывания с такими, как KeyEvent.VK_S
для левой и KeyEvent.VK_F
для правой, он будет работать! теперь почему?
Как исправить, как сделать привязки клавиш стрелок влево и вправо для JScrollBar JButtons, когда редактируемый компонент сосуществует?
Это два рабочих кода в стиле SSCCE. Первый содержит JScrollBar без редактируемых компонентов, второй содержит JScrollBar с JTextArea.
Первый будет работать нормально, так как он будет реагировать на стрелки влево и вправо клавиатуры. (Он не содержит редактируемые компоненты)
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();
}
});
}
}
[пожалуйста, есть какой-то diffrencies ???] (HTTP : //stackoverflow.com/questions/11183536/scrollbar-movement-not-smooth-in-jscrollpane-in-swing/11183706#11183706) – mKorbel
Мне кажется, что вам нужно играть с этим атрибутом 'JComponent.WHEN_IN_FOCUSED_WINDOW' из 'InputMap'. Поскольку то же самое действие KeyBindings применяется к редактируемому 'JTextField/JTextArea', так что либо вы должны оставить эту вещь пустой для' getInputMap(). Put() '. В более простых терминах тот же ключ связан с редактируемым 'JTextField/JTextArea', поэтому' WHEN_FOCUSED' будет иметь приоритет над 'WHEN_IN_FOCUSED_WINDOW', __IMHO__, как уже указано в [KeyBindings] (http://docs.oracle.com/JavaSE/учебник/uiswing/разное/KeyBinding.html) :-) –
@Andrew Лучше отредактировать его, вместо того, чтобы саркастически комментировать на английском неправильном использовании, потому что английский не мой первый язык, и именно так я пытался выразить вещи на английском языке. Я всегда стараюсь делать все возможное. Спасибо –