Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: GUI и Java FX приложения > KeyListener на JPanel


Автор: MrLjaO 26.4.2006, 11:39
Как повесить KeyListener на панель?
просто так повесив листенер на панель он не работает.

Если добавить на панел кнопку - то при нажатии на неё (фокус на кнопке)   KeyListener на панели срабатывает ,
но если у меня на панели только Лабле - как мне быть? 

Автор: Ortega 26.4.2006, 11:55
Код

panel.getActionMap().put(key, someAction);
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(someKeyStroke, key);

someAction - что должно происходить по событию
someKeyStroke  - комбинация клавиш, которая инициирует действие. Нямс, удобнее всего получать keyStroke следующим образом:     
Код

KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, KeyEvent.CTRL_MASK);

 
Если сразу не сработает, попрбуй поиграться с условием получения InputMap. Варианты:
WHEN_IN_FOCUSED_WINDOW, WHEN_FOCUSED, WHEN_ANCESTOR_OF_FOCUSED_COMPONENT 

Автор: MrLjaO 26.4.2006, 12:38
Признаться не совсем понятно что такое key, someAction.
Затдача такова на аплете несколько панелей .. при нажатии мышкой на одну из панелей если мы нажимаем затем клавишу F1  - грузиться Help. В каком виде не важно .. просто идёт некая процедура.

мне не совсем понятна работы пары 

panel.getActionMap().put(key, someAction);
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(someKeyStroke, key);

и как собственно взаимодействуют Key и SomeAction

Где идёт отлов "фокуса" и нажатия? 

Автор: Ortega 26.4.2006, 12:59
Раз нажатие мышкой - значит нужно условие WHEN_ANCESTOR_OF_FOCUSED_COMPONENT

key - это некий ключ, например, строка, который будет идентифицировать экшн. 
key нужен для того, чтобы при срабатывании комбинации, описанной keyStroke'ом компонент мог вытащить из ActionMap'а action и вызвать его метод actionPerformed(...). 

Допустим, Help грузится с помощью метода help() той же панели. Тогда someAction может иметь такой вид: 
Код

    Action someAction = new AbstractAction() {
      public void actionPerformed(ActionEvent e) {
        panel.help();
      }
    };

а приведенный мною код выглядеть примерно так:
Код

panel.getActionMap().put("help", someAction);
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0), "help");


Цитата(MrLjaO @  26.4.2006,  12:38 Найти цитируемый пост)
и как собственно взаимодействуют Key и SomeAction

Где идёт отлов "фокуса" и нажатия?  

Вся прелесть в том, что это происходит на уровне самой панели и об этом заботиться не нужно.  

Автор: MrLjaO 26.4.2006, 13:32
Да .. рабоает ... )) За это спасибо )) 
НО
Во превых  . при данном раскладе - 
не зависимо то того , было ли на жатие на панель срабатывает листенер (тоесть ему грубо говря побоку на какую панель мы кликнули последний раз или даже кликали ли вообще)
Во вторых если мы сделали 2 панели  и на них обоих повесили "листенеры" данным способом - срабатывает последний повешаный Action. 
Вот упрощённый код моего проекта
 
Код


import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.beans.PropertyChangeListener;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;

public class PanelListener extends JFrame{
    JPanel panel1 = new JPanel();
    JPanel panel2 = new JPanel();
    
    PanelListener(){
        setSize(300,200);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        Container c = getContentPane();
        c.setLayout(new GridBagLayout());
        init();
        
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.BOTH;
        gbc.anchor = GridBagConstraints.CENTER;
        
        gbc.gridx=0;
        gbc.gridy=0;
        c.add(panel1,gbc);
        
        gbc.gridx=1;
        gbc.gridy=1;
        c.add(panel2,gbc);
            
    }
    
    private void init(){
        panel1.setLayout(new GridBagLayout());
        panel2.setLayout(new GridBagLayout());
        
        
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.anchor = GridBagConstraints.CENTER;
        gbc.gridx=0;
        gbc.gridy=0;
        
        panel1.setBorder(BorderFactory.createEtchedBorder());
        panel2.setBorder(BorderFactory.createEtchedBorder());

        panel1.add(new JLabel("Test1"),gbc);
        panel2.add(new JLabel("Test2"),gbc);
        
        initListener();
        
    }
    public void initListener(){
        panel1.setFocusable(true);
        panel2.setFocusable(true);
        
                
        panel1.getActionMap().put("help1",someAction1);
        panel1.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
                KeyStroke.getKeyStroke(KeyEvent.VK_F1,0),"help1");
        
        panel2.getActionMap().put("help2",someAction2);
        panel2.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
                KeyStroke.getKeyStroke(KeyEvent.VK_F1,0),"help2");
    }
    AbstractAction someAction1 = new AbstractAction(){

        public void actionPerformed(ActionEvent e) {
            System.out.println("Test Listeners1");            
        }
        
    };
    AbstractAction someAction2 = new AbstractAction(){

        public void actionPerformed(ActionEvent e) {
            System.out.println("Test Listeners2");            
        }
        
    };

    public static void main(String[] args) {
        PanelListener pl = new PanelListener();
        pl.show();
        
    }
    

}
 

Автор: Ortega 26.4.2006, 13:51
JComponent.WHEN_IN_FOCUSED_WINDOW замени на JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT или JComponent.WHEN_FOCUSED. Не уверен, что именно сработает 

Автор: MrLjaO 27.4.2006, 10:25
Попробовал  варианты WHEN_IN_FOCUSED_WINDOW, WHEN_FOCUSED, WHEN_ANCESTOR_OF_FOCUSED_COMPONENT 

 WHEN_ANCESTOR_OF_FOCUSED_COMPONENT  -  работает  .. но только тогда когда какой то компанент на панели "держит фокус".
Тоесть если кинуть кнопку  и нажать на неё (взять фокус)-  то будет работать ....  Но если кликнуть на Jlable то не работает ...
по прежнему мучаюсь  - ничег не выходит .... 

Автор: MrLjaO 27.4.2006, 11:38
Ну вот! Разобрался ! Кому интересна эта тема .. или столкнулся с таким же .. читайте ниже.

Добиться нужного эфекта через 
Код

panel.getActionMap().put("help", someAction);
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0), "help");

Мне к сожаленю не удалось .. поэтому воплотил я этот замысел следующим образом.

Просто так (нажатием мышкой ) панели фокус не передашь (если конечно она не содержит сомпонентов ... "могущих" держать фокус .
Поэтому делаем следующим образом - 
Код

JPanel panel1 = new JPanel();
/*
тут на неё вешаем что нить ... лабле, кнопки ,  .. что угодно
*/
//  Затем вешаем МаусЛистенер
panel1.addMouseListener(new MouseAdapter(){ 
            public void mousePressed(MouseEvent me){
             panel1 .requestFocus();
             }
            });
// Ну а после прсто и легко на панель вешаем кейЛистенер

        panel1.addKeyListener(new KeyListener(){
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_F1) {  //  проверяем что нажата нужная клавиша
                    System.out.println("F1 ");
                }
            }
            public void keyReleased(KeyEvent e) {
            }
            public void keyTyped(KeyEvent e) {
            }
        });



Всё работает .. проверено. 
 

Автор: Ortega 27.4.2006, 11:39
Попробуй так
Код

  public void initListener(){
      MouseListener ml = new MouseAdapter() {
        
        @Override
        public void mouseClicked(MouseEvent e) {
          e.getComponent().requestFocusInWindow();
        }
      
      }; 
      panel1.addMouseListener(ml);
      panel2.addMouseListener(ml);
              
      panel1.getActionMap().put("help1",someAction1);
      panel1.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
              KeyStroke.getKeyStroke(KeyEvent.VK_F1,0),"help1");
      
      panel2.getActionMap().put("help2",someAction2);
      panel2.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
              KeyStroke.getKeyStroke(KeyEvent.VK_F1,0),"help2");
  }
  AbstractAction someAction1 = new AbstractAction(){
      public void actionPerformed(ActionEvent e) {
          System.out.println("Test Listeners1");            
      }
      
  };
  AbstractAction someAction2 = new AbstractAction(){
      public void actionPerformed(ActionEvent e) {
          System.out.println("Test Listeners2");            
      }
      
  };

 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)