2013-09-04 6 views
3

(Все будет ясно в коде после описания)Почему 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(); 
     } 
     }); 
    } 
} 
+1

[пожалуйста, есть какой-то diffrencies ???] (HTTP : //stackoverflow.com/questions/11183536/scrollbar-movement-not-smooth-in-jscrollpane-in-swing/11183706#11183706) – mKorbel

+1

Мне кажется, что вам нужно играть с этим атрибутом '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) :-) –

+1

@Andrew Лучше отредактировать его, вместо того, чтобы саркастически комментировать на английском неправильном использовании, потому что английский не мой первый язык, и именно так я пытался выразить вещи на английском языке. Я всегда стараюсь делать все возможное. Спасибо –

ответ

0

Это потому, что JTextArea крадет ваши ключевые штрихи:

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

Взгляните на BasicTextUI.installKeyboardActions()

 Смежные вопросы

  • Нет связанных вопросов^_^