Как получать ключевые события во время перетаскивания? - PullRequest
3 голосов
/ 16 декабря 2009

В настоящее время я пытаюсь получать ключевые события во время перетаскивания, но мне кажется, что при перетаскивании фокус убирается, поэтому я не могу прослушивать какие-либо ключевые события.

Я перетаскиваю подкласс JComponent, который реализует KeyListener и запрашивает фокус в методе dragEnter DragSourceListener, но я предполагаю, что фокус впоследствии будет удален из него.

Теперь, у кого есть фокус и как я могу забрать его обратно моему JComponent. Или есть другой подход, который больше подходит для DDD?

Заранее спасибо.

UPDATE

Для выполнения этой работы требуется много кода, поэтому я собираюсь опубликовать только некоторые фрагменты, чтобы показать вам, что я пытаюсь сделать:

public class Stone extends JComponent implements Serializable, KeyListener {

    public Stone(...) {

        //...

        setFocusable(true);
        addKeyListener(this);

        this.dragSource = DragSource.getDefaultDragSource();
        this.dgListener = new StoneDGListener();
        this.dsListener = new StoneDSListener();

        this.dragSource.createDefaultDragGestureRecognizer(
            this, 
            DnDConstants.ACTION_MOVE, 
            this.dgListener
        );

        //...

    }

    //...

    public void keyPressed(KeyEvent e) {
        System.out.println("Stone: "+e.getKeyCode());
    }

    //...

    public class StoneDSListener implements DragSourceListener, Serializable {

        //...       

        @Override
        public void dragEnter(DragSourceDragEvent dsde) {
            //...   
            Stone.this.requestFocus();
            addKeyListener(Stone.this);
        }

        //...
    }
}

Что происходит, так это то, что перед перетаскиванием компонента Stone мой JPanel имеет фокус, поэтому он получает любые клавиши, которые я нажимаю. Во время перетаскивания я не могу слушать какие-либо нажатые клавиши (поэтому я не знаю, кто получил фокус), даже если я запрашиваю его, когда в dragEnter() и после того, как я отпускаю Stone, любые события клавиш отправляются на Stone.

Это, вероятно, не важно для вопроса, но для иллюстрации того, что я делаю, вот скриншот:

изображение, показывающее «перетаскивание» http://img685.imageshack.us/img685/1884/pico.png (Здесь я перетаскиваю Stone из коллекции ниже на игровое поле вверху). В этом состоянии я не знаю, как узнать, какие клавиши нажаты. Мне нужно понять это, чтобы иметь возможность вращать Stone.

1 Ответ

3 голосов
/ 23 декабря 2009

Не уверен, у кого есть фокус во время перетаскивания. Но альтернативным решением вашей проблемы было бы добавить KeyEventDispatcher для вашего класса Stone в KeyboardFocusManager . Из JavaDoc:

KeyboardFocusManager - это и централизованное расположение клиентского кода для запроса владельца фокуса и инициирования изменений фокуса, и диспетчер событий для все FocusEvents, WindowEvents, связанные с фокусом, и KeyEvents + .

+ мой акцент.

В основном мы используем подобный код для перехвата KeyEvents до того, как они попадут в Компонент, который имеет фокус.

Просто дал ему быстрый тест для вашего конкретного контекста перетаскивания, и он, кажется, работает нормально (если ваше приложение сосредоточено на операционной системе). По сути, что-то вроде:

Public Stone(...) {
    // ...

    KeyboardFocusManager fm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
    fm.addKeyEventDispatcher(
        new KeyEventDispatcher() {
            public boolean dispatchKeyEvent(KeyEvent e) {
                System.out.println("Key Press: " + e.getKeyChar());
                return false;
            }            
        } 
    );

   // ... 
}

Вам нужно будет немного поработать над включением и отключением, когда пользователь больше не перетаскивает, поскольку мой тест в настоящее время печатает все время.

Мне также интересно, можно ли использовать KeyboardFocusManager, чтобы определить, кто на самом деле получает фокус при перетаскивании?

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...